Mercurial > hg > nginx
annotate src/http/modules/ngx_http_realip_module.c @ 4253:6efec8b1ff52 stable-1.0
Merging r4193, r4194:
Autoindex fixes:
*) Autoindex: escape '?' in file names.
For files with '?' in their names autoindex generated links with '?' not
escaped. This resulted in effectively truncated links as '?' indicates
query string start.
This is an updated version of the patch originally posted at [1]. It
introduces generic NGX_ESCAPE_URI_COMPONENT which escapes everything but
unreserved characters as per RFC 3986. This approach also renders unneeded
special colon processing (as colon is percent-encoded now), it's dropped
accordingly.
[1] http://nginx.org/pipermail/nginx-devel/2010-February/000112.html
*) Autoindex: escape html in file names.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 01 Nov 2011 14:09:15 +0000 |
parents | 8017f9bda3f6 |
children | d620f497c50f |
rev | line source |
---|---|
573 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
12 #define NGX_HTTP_REALIP_XREALIP 0 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
13 #define NGX_HTTP_REALIP_XFWD 1 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
14 #define NGX_HTTP_REALIP_HEADER 2 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
15 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
16 |
573 | 17 typedef struct { |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
18 in_addr_t mask; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
19 in_addr_t addr; |
573 | 20 } ngx_http_realip_from_t; |
21 | |
22 | |
23 typedef struct { | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
24 ngx_array_t *from; /* array of ngx_http_realip_from_t */ |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
25 ngx_uint_t type; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
26 ngx_uint_t hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
27 ngx_str_t header; |
3274 | 28 #if (NGX_HAVE_UNIX_DOMAIN) |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
29 ngx_uint_t unixsock; /* unsigned unixsock:2; */ |
3274 | 30 #endif |
573 | 31 } ngx_http_realip_loc_conf_t; |
32 | |
33 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
34 typedef struct { |
3274 | 35 ngx_connection_t *connection; |
36 struct sockaddr *sockaddr; | |
37 socklen_t socklen; | |
38 ngx_str_t addr_text; | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
39 } ngx_http_realip_ctx_t; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
40 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
41 |
573 | 42 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); |
3274 | 43 static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, |
44 size_t len); | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
45 static void ngx_http_realip_cleanup(void *data); |
573 | 46 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, |
47 void *conf); | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
48 static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
573 | 49 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); |
50 static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, | |
51 void *parent, void *child); | |
681 | 52 static ngx_int_t ngx_http_realip_init(ngx_conf_t *cf); |
573 | 53 |
54 | |
55 static ngx_command_t ngx_http_realip_commands[] = { | |
56 | |
57 { ngx_string("set_real_ip_from"), | |
58 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
59 ngx_http_realip_from, | |
60 NGX_HTTP_LOC_CONF_OFFSET, | |
61 0, | |
62 NULL }, | |
63 | |
64 { ngx_string("real_ip_header"), | |
65 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
66 ngx_http_realip, |
573 | 67 NGX_HTTP_LOC_CONF_OFFSET, |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
68 0, |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
69 NULL }, |
573 | 70 |
71 ngx_null_command | |
72 }; | |
73 | |
74 | |
75 | |
667 | 76 static ngx_http_module_t ngx_http_realip_module_ctx = { |
573 | 77 NULL, /* preconfiguration */ |
681 | 78 ngx_http_realip_init, /* postconfiguration */ |
573 | 79 |
80 NULL, /* create main configuration */ | |
81 NULL, /* init main configuration */ | |
82 | |
83 NULL, /* create server configuration */ | |
84 NULL, /* merge server configuration */ | |
85 | |
86 ngx_http_realip_create_loc_conf, /* create location configuration */ | |
87 ngx_http_realip_merge_loc_conf /* merge location configuration */ | |
88 }; | |
89 | |
90 | |
91 ngx_module_t ngx_http_realip_module = { | |
92 NGX_MODULE_V1, | |
93 &ngx_http_realip_module_ctx, /* module context */ | |
94 ngx_http_realip_commands, /* module directives */ | |
95 NGX_HTTP_MODULE, /* module type */ | |
96 NULL, /* init master */ | |
681 | 97 NULL, /* init module */ |
573 | 98 NULL, /* init process */ |
99 NULL, /* init thread */ | |
100 NULL, /* exit thread */ | |
101 NULL, /* exit process */ | |
102 NULL, /* exit master */ | |
103 NGX_MODULE_V1_PADDING | |
104 }; | |
105 | |
106 | |
107 static ngx_int_t | |
108 ngx_http_realip_handler(ngx_http_request_t *r) | |
109 { | |
110 u_char *ip, *p; | |
111 size_t len; | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
112 ngx_uint_t i, hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
113 ngx_list_part_t *part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
114 ngx_table_elt_t *header; |
573 | 115 struct sockaddr_in *sin; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
116 ngx_connection_t *c; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
117 ngx_http_realip_ctx_t *ctx; |
573 | 118 ngx_http_realip_from_t *from; |
119 ngx_http_realip_loc_conf_t *rlcf; | |
120 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
121 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
122 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
123 if (ctx) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
124 return NGX_DECLINED; |
573 | 125 } |
126 | |
127 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); | |
128 | |
3291
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
129 if (rlcf->from == NULL |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
130 #if (NGX_HAVE_UNIX_DOMAIN) |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
131 && !rlcf->unixsock |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
132 #endif |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
133 ) |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
134 { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
135 return NGX_DECLINED; |
573 | 136 } |
137 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
138 switch (rlcf->type) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
139 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
140 case NGX_HTTP_REALIP_XREALIP: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
141 |
573 | 142 if (r->headers_in.x_real_ip == NULL) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
143 return NGX_DECLINED; |
573 | 144 } |
145 | |
146 len = r->headers_in.x_real_ip->value.len; | |
147 ip = r->headers_in.x_real_ip->value.data; | |
148 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
149 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
150 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
151 case NGX_HTTP_REALIP_XFWD: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
152 |
573 | 153 if (r->headers_in.x_forwarded_for == NULL) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
154 return NGX_DECLINED; |
573 | 155 } |
156 | |
157 len = r->headers_in.x_forwarded_for->value.len; | |
158 ip = r->headers_in.x_forwarded_for->value.data; | |
159 | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
160 for (p = ip + len - 1; p > ip; p--) { |
573 | 161 if (*p == ' ' || *p == ',') { |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
162 p++; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
163 len -= p - ip; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
164 ip = p; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
165 break; |
573 | 166 } |
167 } | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
168 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
169 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
170 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
171 default: /* NGX_HTTP_REALIP_HEADER */ |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
172 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
173 part = &r->headers_in.headers.part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
174 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
175 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
176 hash = rlcf->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
177 len = rlcf->header.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
178 p = rlcf->header.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
179 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
180 for (i = 0; /* void */ ; i++) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
181 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
182 if (i >= part->nelts) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
183 if (part->next == NULL) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
184 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
185 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
186 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
187 part = part->next; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
188 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
189 i = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
190 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
191 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
192 if (hash == header[i].hash |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
193 && len == header[i].key.len |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
194 && ngx_strncmp(p, header[i].lowcase_key, len) == 0) |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
195 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
196 len = header[i].value.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
197 ip = header[i].value.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
198 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
199 goto found; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
200 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
201 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
202 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
203 return NGX_DECLINED; |
573 | 204 } |
205 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
206 found: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
207 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
208 c = r->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
209 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
210 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
211 |
573 | 212 /* AF_INET only */ |
213 | |
3274 | 214 if (c->sockaddr->sa_family == AF_INET) { |
215 sin = (struct sockaddr_in *) c->sockaddr; | |
216 | |
217 from = rlcf->from->elts; | |
218 for (i = 0; i < rlcf->from->nelts; i++) { | |
219 | |
220 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
221 "realip: %08XD %08XD %08XD", | |
222 sin->sin_addr.s_addr, from[i].mask, from[i].addr); | |
223 | |
224 if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { | |
225 return ngx_http_realip_set_addr(r, ip, len); | |
226 } | |
227 } | |
228 } | |
229 | |
230 #if (NGX_HAVE_UNIX_DOMAIN) | |
231 | |
232 if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) { | |
233 return ngx_http_realip_set_addr(r, ip, len); | |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
234 } |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
235 |
3274 | 236 #endif |
573 | 237 |
3274 | 238 return NGX_DECLINED; |
239 } | |
240 | |
573 | 241 |
3274 | 242 static ngx_int_t |
243 ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len) | |
244 { | |
245 u_char *p; | |
246 ngx_int_t rc; | |
247 ngx_addr_t addr; | |
248 ngx_connection_t *c; | |
249 ngx_pool_cleanup_t *cln; | |
250 ngx_http_realip_ctx_t *ctx; | |
573 | 251 |
3274 | 252 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t)); |
253 if (cln == NULL) { | |
254 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
255 } | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
256 |
3274 | 257 ctx = cln->data; |
258 ngx_http_set_ctx(r, ctx, ngx_http_realip_module); | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
259 |
3274 | 260 c = r->connection; |
261 | |
262 rc = ngx_parse_addr(c->pool, &addr, ip, len); | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
263 |
3274 | 264 switch (rc) { |
265 case NGX_DECLINED: | |
266 return NGX_DECLINED; | |
267 case NGX_ERROR: | |
268 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
269 default: /* NGX_OK */ | |
270 break; | |
271 } | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
272 |
3274 | 273 p = ngx_pnalloc(c->pool, len); |
274 if (p == NULL) { | |
275 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
276 } | |
1118
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
277 |
3274 | 278 ngx_memcpy(p, ip, len); |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
279 |
3274 | 280 cln->handler = ngx_http_realip_cleanup; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
281 |
3274 | 282 ctx->connection = c; |
283 ctx->sockaddr = c->sockaddr; | |
284 ctx->socklen = c->socklen; | |
285 ctx->addr_text = c->addr_text; | |
573 | 286 |
3274 | 287 c->sockaddr = addr.sockaddr; |
288 c->socklen = addr.socklen; | |
289 c->addr_text.len = len; | |
290 c->addr_text.data = p; | |
573 | 291 |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
292 return NGX_DECLINED; |
573 | 293 } |
294 | |
295 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
296 static void |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
297 ngx_http_realip_cleanup(void *data) |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
298 { |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
299 ngx_http_realip_ctx_t *ctx = data; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
300 |
3273
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
301 ngx_connection_t *c; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
302 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
303 c = ctx->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
304 |
3273
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
305 c->sockaddr = ctx->sockaddr; |
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
306 c->socklen = ctx->socklen; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
307 c->addr_text = ctx->addr_text; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
308 } |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
309 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
310 |
573 | 311 static char * |
312 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
313 { | |
314 ngx_http_realip_loc_conf_t *rlcf = conf; | |
315 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
316 ngx_int_t rc; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
317 ngx_str_t *value; |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
318 ngx_cidr_t cidr; |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
319 ngx_http_realip_from_t *from; |
573 | 320 |
3274 | 321 value = cf->args->elts; |
322 | |
323 #if (NGX_HAVE_UNIX_DOMAIN) | |
324 | |
325 if (ngx_strcmp(value[1].data, "unix:") == 0) { | |
326 rlcf->unixsock = 1; | |
327 return NGX_CONF_OK; | |
328 } | |
329 | |
330 #endif | |
331 | |
573 | 332 if (rlcf->from == NULL) { |
333 rlcf->from = ngx_array_create(cf->pool, 2, | |
334 sizeof(ngx_http_realip_from_t)); | |
335 if (rlcf->from == NULL) { | |
336 return NGX_CONF_ERROR; | |
337 } | |
338 } | |
339 | |
340 from = ngx_array_push(rlcf->from); | |
341 if (from == NULL) { | |
342 return NGX_CONF_ERROR; | |
343 } | |
344 | |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
345 rc = ngx_ptocidr(&value[1], &cidr); |
1380
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
346 |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
347 if (rc == NGX_ERROR) { |
573 | 348 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", |
349 &value[1]); | |
350 return NGX_CONF_ERROR; | |
351 } | |
352 | |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
353 if (cidr.family != AF_INET) { |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
354 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
3280
9285e936c79d
fix directive name in error message: "set_realip_from" to "set_real_ip_from"
Igor Sysoev <igor@sysoev.ru>
parents:
3279
diff
changeset
|
355 "\"set_real_ip_from\" supports IPv4 only"); |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
356 return NGX_CONF_ERROR; |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
357 } |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
358 |
1380
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
359 if (rc == NGX_DONE) { |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
360 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
361 "low address bits of %V are meaningless", &value[1]); |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
362 } |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
363 |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
364 from->mask = cidr.u.in.mask; |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
365 from->addr = cidr.u.in.addr; |
573 | 366 |
367 return NGX_CONF_OK; | |
368 } | |
369 | |
370 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
371 static char * |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
372 ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
373 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
374 ngx_http_realip_loc_conf_t *rlcf = conf; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
375 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
376 ngx_str_t *value; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
377 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
378 value = cf->args->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
379 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
380 if (ngx_strcmp(value[1].data, "X-Real-IP") == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
381 rlcf->type = NGX_HTTP_REALIP_XREALIP; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
382 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
383 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
384 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
385 if (ngx_strcmp(value[1].data, "X-Forwarded-For") == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
386 rlcf->type = NGX_HTTP_REALIP_XFWD; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
387 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
388 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
389 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
390 rlcf->type = NGX_HTTP_REALIP_HEADER; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
391 rlcf->hash = ngx_hash_strlow(value[1].data, value[1].data, value[1].len); |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
392 rlcf->header = value[1]; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
393 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
394 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
395 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
396 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
397 |
573 | 398 static void * |
399 ngx_http_realip_create_loc_conf(ngx_conf_t *cf) | |
400 { | |
401 ngx_http_realip_loc_conf_t *conf; | |
402 | |
403 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t)); | |
404 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2537
diff
changeset
|
405 return NULL; |
573 | 406 } |
407 | |
408 /* | |
409 * set by ngx_pcalloc(): | |
410 * | |
411 * conf->from = NULL; | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
412 * conf->hash = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
413 * conf->header = { 0, NULL }; |
573 | 414 */ |
415 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
416 conf->type = NGX_CONF_UNSET_UINT; |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
417 #if (NGX_HAVE_UNIX_DOMAIN) |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
418 conf->unixsock = 2; |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
419 #endif |
573 | 420 |
421 return conf; | |
422 } | |
423 | |
424 | |
425 static char * | |
426 ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
427 { | |
428 ngx_http_realip_loc_conf_t *prev = parent; | |
429 ngx_http_realip_loc_conf_t *conf = child; | |
430 | |
431 if (conf->from == NULL) { | |
432 conf->from = prev->from; | |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
433 } |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
434 |
3274 | 435 #if (NGX_HAVE_UNIX_DOMAIN) |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
436 if (conf->unixsock == 2) { |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
437 conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock; |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
438 } |
3274 | 439 #endif |
573 | 440 |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
441 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP); |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
442 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
443 if (conf->header.len == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
444 conf->hash = prev->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
445 conf->header = prev->header; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
446 } |
573 | 447 |
448 return NGX_CONF_OK; | |
449 } | |
450 | |
451 | |
452 static ngx_int_t | |
681 | 453 ngx_http_realip_init(ngx_conf_t *cf) |
573 | 454 { |
455 ngx_http_handler_pt *h; | |
456 ngx_http_core_main_conf_t *cmcf; | |
457 | |
681 | 458 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
573 | 459 |
460 h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); | |
461 if (h == NULL) { | |
462 return NGX_ERROR; | |
463 } | |
464 | |
465 *h = ngx_http_realip_handler; | |
466 | |
581 | 467 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); |
573 | 468 if (h == NULL) { |
469 return NGX_ERROR; | |
470 } | |
471 | |
472 *h = ngx_http_realip_handler; | |
473 | |
474 return NGX_OK; | |
475 } |