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