Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_realip_module.c @ 5110:0bbdd966a383
Request body: next upstream fix.
After introduction of chunked request body handling in 1.3.9 (r4931),
r->request_body->bufs buffers have b->start pointing to original buffer
start (and b->pos pointing to real data of this particular buffer).
While this is ok as per se, it caused bad things (usually original request
headers included before the request body) after reinit of the request
chain in ngx_http_upstream_reinit() while sending the request to a next
upstream server (which used to do b->pos = b->start for each buffer
in the request chain).
Patch by Piotr Sikora.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 14 Mar 2013 12:28:53 +0000 |
parents | f7fe817c92a2 |
children | 05ba5bce31e0 |
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 { |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
19 ngx_array_t *from; /* array of ngx_cidr_t */ |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
20 ngx_uint_t type; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
21 ngx_uint_t hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
22 ngx_str_t header; |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
23 ngx_flag_t recursive; |
573 | 24 } ngx_http_realip_loc_conf_t; |
25 | |
26 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
27 typedef struct { |
3274 | 28 ngx_connection_t *connection; |
29 struct sockaddr *sockaddr; | |
30 socklen_t socklen; | |
31 ngx_str_t addr_text; | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
32 } ngx_http_realip_ctx_t; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
33 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
34 |
573 | 35 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
36 static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
37 ngx_addr_t *addr); |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
38 static void ngx_http_realip_cleanup(void *data); |
573 | 39 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, |
40 void *conf); | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
41 static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
573 | 42 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); |
43 static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, | |
44 void *parent, void *child); | |
681 | 45 static ngx_int_t ngx_http_realip_init(ngx_conf_t *cf); |
573 | 46 |
47 | |
48 static ngx_command_t ngx_http_realip_commands[] = { | |
49 | |
50 { ngx_string("set_real_ip_from"), | |
51 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
52 ngx_http_realip_from, | |
53 NGX_HTTP_LOC_CONF_OFFSET, | |
54 0, | |
55 NULL }, | |
56 | |
57 { ngx_string("real_ip_header"), | |
58 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
|
59 ngx_http_realip, |
573 | 60 NGX_HTTP_LOC_CONF_OFFSET, |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
61 0, |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
62 NULL }, |
573 | 63 |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
64 { ngx_string("real_ip_recursive"), |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
65 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
66 ngx_conf_set_flag_slot, |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
67 NGX_HTTP_LOC_CONF_OFFSET, |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
68 offsetof(ngx_http_realip_loc_conf_t, recursive), |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
69 NULL }, |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
70 |
573 | 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 { | |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
110 u_char *p; |
573 | 111 size_t len; |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
112 ngx_str_t *value; |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
113 ngx_uint_t i, hash; |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
114 ngx_addr_t addr; |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
115 ngx_array_t *xfwd; |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
116 ngx_list_part_t *part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
117 ngx_table_elt_t *header; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
118 ngx_connection_t *c; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
119 ngx_http_realip_ctx_t *ctx; |
573 | 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 | |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
130 if (rlcf->from == NULL) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
131 return NGX_DECLINED; |
573 | 132 } |
133 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
134 switch (rlcf->type) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
135 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
136 case NGX_HTTP_REALIP_XREALIP: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
137 |
573 | 138 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
|
139 return NGX_DECLINED; |
573 | 140 } |
141 | |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
142 value = &r->headers_in.x_real_ip->value; |
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
143 xfwd = NULL; |
573 | 144 |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
145 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
146 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
147 case NGX_HTTP_REALIP_XFWD: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
148 |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
149 xfwd = &r->headers_in.x_forwarded_for; |
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
150 |
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
151 if (xfwd->elts == NULL) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
152 return NGX_DECLINED; |
573 | 153 } |
154 | |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
155 value = NULL; |
573 | 156 |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
157 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
158 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
159 default: /* NGX_HTTP_REALIP_HEADER */ |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
160 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
161 part = &r->headers_in.headers.part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
162 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
163 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
164 hash = rlcf->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
165 len = rlcf->header.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
166 p = rlcf->header.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
167 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
168 for (i = 0; /* void */ ; i++) { |
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 if (i >= part->nelts) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
171 if (part->next == NULL) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
172 break; |
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 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
175 part = part->next; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
176 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
177 i = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
178 } |
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 if (hash == header[i].hash |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
181 && len == header[i].key.len |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
182 && 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
|
183 { |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
184 value = &header[i].value; |
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
185 xfwd = NULL; |
2257
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 goto found; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
188 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
189 } |
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 return NGX_DECLINED; |
573 | 192 } |
193 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
194 found: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
195 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
196 c = r->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
197 |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
198 addr.sockaddr = c->sockaddr; |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
199 addr.socklen = c->socklen; |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
200 /* addr.name = c->addr_text; */ |
3274 | 201 |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
202 if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from, |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
203 rlcf->recursive) |
5084
f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Ruslan Ermilov <ru@nginx.com>
parents:
4624
diff
changeset
|
204 != NGX_DECLINED) |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
205 { |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
206 return ngx_http_realip_set_addr(r, &addr); |
3274 | 207 } |
208 | |
209 return NGX_DECLINED; | |
210 } | |
211 | |
573 | 212 |
3274 | 213 static ngx_int_t |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
214 ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr) |
3274 | 215 { |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
216 size_t len; |
3274 | 217 u_char *p; |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
218 u_char text[NGX_SOCKADDR_STRLEN]; |
3274 | 219 ngx_connection_t *c; |
220 ngx_pool_cleanup_t *cln; | |
221 ngx_http_realip_ctx_t *ctx; | |
573 | 222 |
3274 | 223 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t)); |
224 if (cln == NULL) { | |
225 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
226 } | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
227 |
3274 | 228 ctx = cln->data; |
229 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
|
230 |
3274 | 231 c = r->connection; |
232 | |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
233 len = ngx_sock_ntop(addr->sockaddr, text, NGX_SOCKADDR_STRLEN, 0); |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
234 if (len == 0) { |
3274 | 235 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
236 } | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
237 |
3274 | 238 p = ngx_pnalloc(c->pool, len); |
239 if (p == NULL) { | |
240 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
241 } | |
1118
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
242 |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
243 ngx_memcpy(p, text, len); |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
244 |
3274 | 245 cln->handler = ngx_http_realip_cleanup; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
246 |
3274 | 247 ctx->connection = c; |
248 ctx->sockaddr = c->sockaddr; | |
249 ctx->socklen = c->socklen; | |
250 ctx->addr_text = c->addr_text; | |
573 | 251 |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
252 c->sockaddr = addr->sockaddr; |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
253 c->socklen = addr->socklen; |
3274 | 254 c->addr_text.len = len; |
255 c->addr_text.data = p; | |
573 | 256 |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
257 return NGX_DECLINED; |
573 | 258 } |
259 | |
260 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
261 static void |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
262 ngx_http_realip_cleanup(void *data) |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
263 { |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
264 ngx_http_realip_ctx_t *ctx = data; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
265 |
3273
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
266 ngx_connection_t *c; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
267 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
268 c = ctx->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
269 |
3273
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
270 c->sockaddr = ctx->sockaddr; |
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
271 c->socklen = ctx->socklen; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
272 c->addr_text = ctx->addr_text; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
273 } |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
274 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
275 |
573 | 276 static char * |
277 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
278 { | |
279 ngx_http_realip_loc_conf_t *rlcf = conf; | |
280 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
281 ngx_int_t rc; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
282 ngx_str_t *value; |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
283 ngx_cidr_t *cidr; |
573 | 284 |
3274 | 285 value = cf->args->elts; |
286 | |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
287 if (rlcf->from == NULL) { |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
288 rlcf->from = ngx_array_create(cf->pool, 2, |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
289 sizeof(ngx_cidr_t)); |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
290 if (rlcf->from == NULL) { |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
291 return NGX_CONF_ERROR; |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
292 } |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
293 } |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
294 |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
295 cidr = ngx_array_push(rlcf->from); |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
296 if (cidr == NULL) { |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
297 return NGX_CONF_ERROR; |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
298 } |
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
299 |
3274 | 300 #if (NGX_HAVE_UNIX_DOMAIN) |
301 | |
302 if (ngx_strcmp(value[1].data, "unix:") == 0) { | |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
303 cidr->family = AF_UNIX; |
3274 | 304 return NGX_CONF_OK; |
305 } | |
306 | |
307 #endif | |
308 | |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
309 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
|
310 |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
311 if (rc == NGX_ERROR) { |
573 | 312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", |
313 &value[1]); | |
314 return NGX_CONF_ERROR; | |
315 } | |
316 | |
1380
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
317 if (rc == NGX_DONE) { |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
318 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
|
319 "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
|
320 } |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
321 |
573 | 322 return NGX_CONF_OK; |
323 } | |
324 | |
325 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
326 static char * |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
327 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
|
328 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
329 ngx_http_realip_loc_conf_t *rlcf = conf; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
330 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
331 ngx_str_t *value; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
332 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
333 value = cf->args->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
334 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
335 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
|
336 rlcf->type = NGX_HTTP_REALIP_XREALIP; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
337 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
338 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
339 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
340 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
|
341 rlcf->type = NGX_HTTP_REALIP_XFWD; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
342 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
343 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
344 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
345 rlcf->type = NGX_HTTP_REALIP_HEADER; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
346 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
|
347 rlcf->header = value[1]; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
348 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
349 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
350 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
351 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
352 |
573 | 353 static void * |
354 ngx_http_realip_create_loc_conf(ngx_conf_t *cf) | |
355 { | |
356 ngx_http_realip_loc_conf_t *conf; | |
357 | |
358 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t)); | |
359 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
|
360 return NULL; |
573 | 361 } |
362 | |
363 /* | |
364 * set by ngx_pcalloc(): | |
365 * | |
366 * conf->from = NULL; | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
367 * conf->hash = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
368 * conf->header = { 0, NULL }; |
573 | 369 */ |
370 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
371 conf->type = NGX_CONF_UNSET_UINT; |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
372 conf->recursive = NGX_CONF_UNSET; |
573 | 373 |
374 return conf; | |
375 } | |
376 | |
377 | |
378 static char * | |
379 ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
380 { | |
381 ngx_http_realip_loc_conf_t *prev = parent; | |
382 ngx_http_realip_loc_conf_t *conf = child; | |
383 | |
384 if (conf->from == NULL) { | |
385 conf->from = prev->from; | |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
386 } |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
387 |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
388 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP); |
4624
df93068953c0
realip: chains of trusted proxies and IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4562
diff
changeset
|
389 ngx_conf_merge_value(conf->recursive, prev->recursive, 0); |
2257
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 if (conf->header.len == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
392 conf->hash = prev->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
393 conf->header = prev->header; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
394 } |
573 | 395 |
396 return NGX_CONF_OK; | |
397 } | |
398 | |
399 | |
400 static ngx_int_t | |
681 | 401 ngx_http_realip_init(ngx_conf_t *cf) |
573 | 402 { |
403 ngx_http_handler_pt *h; | |
404 ngx_http_core_main_conf_t *cmcf; | |
405 | |
681 | 406 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
573 | 407 |
408 h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); | |
409 if (h == NULL) { | |
410 return NGX_ERROR; | |
411 } | |
412 | |
413 *h = ngx_http_realip_handler; | |
414 | |
581 | 415 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); |
573 | 416 if (h == NULL) { |
417 return NGX_ERROR; | |
418 } | |
419 | |
420 *h = ngx_http_realip_handler; | |
421 | |
422 return NGX_OK; | |
423 } |