1 /*
2  * Copyright (c) 2010, FRiCKLE Piotr Sikora <info@frickle.com>
3  * Copyright (c) 2009-2010, Xiaozhe Wang <chaoslawful@gmail.com>
4  * Copyright (c) 2009-2010, Yichun Zhang <agentzh@gmail.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef _NGX_POSTGRES_MODULE_H_
30 #define _NGX_POSTGRES_MODULE_H_
31 
32 #include <nginx.h>
33 #include <ngx_core.h>
34 #include <ngx_http.h>
35 #include <libpq-fe.h>
36 
37 
38 extern ngx_module_t  ngx_postgres_module;
39 
40 
41 typedef struct {
42     ngx_http_script_code_pt             code;
43     ngx_uint_t                          empty;
44 } ngx_postgres_escape_t;
45 
46 typedef struct {
47     ngx_uint_t                          key;
48     ngx_str_t                           sv;
49     ngx_http_complex_value_t           *cv;
50 } ngx_postgres_mixed_t;
51 
52 typedef struct {
53     ngx_uint_t                          key;
54     ngx_int_t                           status;
55     ngx_str_t                           location;
56 } ngx_postgres_rewrite_t;
57 
58 typedef struct {
59     ngx_int_t                           row;
60     ngx_int_t                           column;
61     u_char                             *col_name;
62     ngx_uint_t                          required;
63 } ngx_postgres_value_t;
64 
65 typedef struct {
66     ngx_uint_t                          idx;
67     ngx_http_variable_t                *var;
68     ngx_postgres_value_t                value;
69 } ngx_postgres_variable_t;
70 
71 typedef struct {
72     ngx_uint_t                          methods_set;
73     ngx_array_t                        *methods; /* method-specific */
74     ngx_postgres_mixed_t               *def;     /* default */
75 } ngx_postgres_query_conf_t;
76 
77 typedef struct ngx_postgres_rewrite_conf_s ngx_postgres_rewrite_conf_t;
78 
79 typedef ngx_int_t (*ngx_postgres_rewrite_handler_pt)
80     (ngx_http_request_t *, ngx_postgres_rewrite_conf_t *);
81 
82 struct ngx_postgres_rewrite_conf_s {
83     /* condition */
84     ngx_uint_t                          key;
85     ngx_postgres_rewrite_handler_pt     handler;
86     /* methods */
87     ngx_uint_t                          methods_set;
88     ngx_array_t                        *methods; /* method-specific */
89     ngx_postgres_rewrite_t             *def;     /* default */
90 };
91 
92 typedef struct {
93     ngx_str_t                           name;
94     ngx_uint_t                          key;
95     ngx_postgres_rewrite_handler_pt     handler;
96 } ngx_postgres_rewrite_enum_t;
97 
98 typedef ngx_int_t (*ngx_postgres_output_handler_pt)
99     (ngx_http_request_t *, PGresult *);
100 
101 typedef struct {
102     ngx_str_t                           name;
103     unsigned                            binary:1;
104     ngx_postgres_output_handler_pt      handler;
105 } ngx_postgres_output_enum_t;
106 
107 typedef struct {
108 #if defined(nginx_version) && (nginx_version >= 8022)
109     ngx_addr_t                         *addrs;
110 #else
111     ngx_peer_addr_t                    *addrs;
112 #endif
113     ngx_uint_t                          naddrs;
114     in_port_t                           port;
115     int                                 family;
116     ngx_str_t                           dbname;
117     ngx_str_t                           user;
118     ngx_str_t                           password;
119 } ngx_postgres_upstream_server_t;
120 
121 typedef struct {
122     struct sockaddr                    *sockaddr;
123     socklen_t                           socklen;
124     ngx_str_t                           name;
125     ngx_str_t                           host;
126     in_port_t                           port;
127     int                                 family;
128     ngx_str_t                           dbname;
129     ngx_str_t                           user;
130     ngx_str_t                           password;
131 } ngx_postgres_upstream_peer_t;
132 
133 typedef struct {
134     ngx_uint_t                          single;
135     ngx_uint_t                          number;
136     ngx_str_t                          *name;
137     ngx_postgres_upstream_peer_t        peer[1];
138 } ngx_postgres_upstream_peers_t;
139 
140 typedef struct {
141     ngx_postgres_upstream_peers_t      *peers;
142     ngx_uint_t                          current;
143     ngx_array_t                        *servers;
144     ngx_pool_t                         *pool;
145     /* keepalive */
146     ngx_flag_t                          single;
147     ngx_queue_t                         free;
148     ngx_queue_t                         cache;
149     ngx_uint_t                          active_conns;
150     ngx_uint_t                          max_cached;
151     ngx_uint_t                          reject;
152 } ngx_postgres_upstream_srv_conf_t;
153 
154 typedef struct {
155     /* upstream */
156     ngx_http_upstream_conf_t            upstream;
157     ngx_http_complex_value_t           *upstream_cv;
158     /* queries */
159     ngx_postgres_query_conf_t           query;
160     /* rewrites */
161     ngx_array_t                        *rewrites;
162     /* output */
163     ngx_postgres_output_handler_pt      output_handler;
164     unsigned                            output_binary:1;
165     /* custom variables */
166     ngx_array_t                        *variables;
167 } ngx_postgres_loc_conf_t;
168 
169 typedef struct {
170     ngx_chain_t                        *response;
171     ngx_int_t                           var_cols;
172     ngx_int_t                           var_rows;
173     ngx_int_t                           var_affected;
174     ngx_str_t                           var_query;
175     ngx_array_t                        *variables;
176     ngx_int_t                           status;
177     PGresult                           *res;
178 } ngx_postgres_ctx_t;
179 
180 
181 ngx_int_t   ngx_postgres_add_variables(ngx_conf_t *);
182 void       *ngx_postgres_create_upstream_srv_conf(ngx_conf_t *);
183 void       *ngx_postgres_create_loc_conf(ngx_conf_t *);
184 char       *ngx_postgres_merge_loc_conf(ngx_conf_t *, void *, void *);
185 char       *ngx_postgres_conf_server(ngx_conf_t *, ngx_command_t *, void *);
186 char       *ngx_postgres_conf_keepalive(ngx_conf_t *, ngx_command_t *, void *);
187 char       *ngx_postgres_conf_pass(ngx_conf_t *, ngx_command_t *, void *);
188 char       *ngx_postgres_conf_query(ngx_conf_t *, ngx_command_t *, void *);
189 char       *ngx_postgres_conf_rewrite(ngx_conf_t *, ngx_command_t *, void *);
190 char       *ngx_postgres_conf_output(ngx_conf_t *, ngx_command_t *, void *);
191 char       *ngx_postgres_conf_set(ngx_conf_t *, ngx_command_t *, void *);
192 char       *ngx_postgres_conf_escape(ngx_conf_t *, ngx_command_t *, void *);
193 
194 ngx_http_upstream_srv_conf_t  *ngx_postgres_find_upstream(ngx_http_request_t *,
195                                    ngx_url_t *);
196 
197 #endif /* _NGX_POSTGRES_MODULE_H_ */
198