Mercurial > hg > nginx
comparison src/http/modules/ngx_http_realip_module.c @ 5084:f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Wed, 27 Feb 2013 13:29:50 +0000 |
parents | df93068953c0 |
children | 05ba5bce31e0 |
comparison
equal
deleted
inserted
replaced
5083:a805dc9c85cd | 5084:f7fe817c92a2 |
---|---|
105 | 105 |
106 | 106 |
107 static ngx_int_t | 107 static ngx_int_t |
108 ngx_http_realip_handler(ngx_http_request_t *r) | 108 ngx_http_realip_handler(ngx_http_request_t *r) |
109 { | 109 { |
110 u_char *ip, *p; | 110 u_char *p; |
111 size_t len; | 111 size_t len; |
112 ngx_str_t *value; | |
112 ngx_uint_t i, hash; | 113 ngx_uint_t i, hash; |
113 ngx_addr_t addr; | 114 ngx_addr_t addr; |
115 ngx_array_t *xfwd; | |
114 ngx_list_part_t *part; | 116 ngx_list_part_t *part; |
115 ngx_table_elt_t *header; | 117 ngx_table_elt_t *header; |
116 ngx_connection_t *c; | 118 ngx_connection_t *c; |
117 ngx_http_realip_ctx_t *ctx; | 119 ngx_http_realip_ctx_t *ctx; |
118 ngx_http_realip_loc_conf_t *rlcf; | 120 ngx_http_realip_loc_conf_t *rlcf; |
135 | 137 |
136 if (r->headers_in.x_real_ip == NULL) { | 138 if (r->headers_in.x_real_ip == NULL) { |
137 return NGX_DECLINED; | 139 return NGX_DECLINED; |
138 } | 140 } |
139 | 141 |
140 len = r->headers_in.x_real_ip->value.len; | 142 value = &r->headers_in.x_real_ip->value; |
141 ip = r->headers_in.x_real_ip->value.data; | 143 xfwd = NULL; |
142 | 144 |
143 break; | 145 break; |
144 | 146 |
145 case NGX_HTTP_REALIP_XFWD: | 147 case NGX_HTTP_REALIP_XFWD: |
146 | 148 |
147 if (r->headers_in.x_forwarded_for == NULL) { | 149 xfwd = &r->headers_in.x_forwarded_for; |
150 | |
151 if (xfwd->elts == NULL) { | |
148 return NGX_DECLINED; | 152 return NGX_DECLINED; |
149 } | 153 } |
150 | 154 |
151 len = r->headers_in.x_forwarded_for->value.len; | 155 value = NULL; |
152 ip = r->headers_in.x_forwarded_for->value.data; | |
153 | 156 |
154 break; | 157 break; |
155 | 158 |
156 default: /* NGX_HTTP_REALIP_HEADER */ | 159 default: /* NGX_HTTP_REALIP_HEADER */ |
157 | 160 |
176 | 179 |
177 if (hash == header[i].hash | 180 if (hash == header[i].hash |
178 && len == header[i].key.len | 181 && len == header[i].key.len |
179 && ngx_strncmp(p, header[i].lowcase_key, len) == 0) | 182 && ngx_strncmp(p, header[i].lowcase_key, len) == 0) |
180 { | 183 { |
181 len = header[i].value.len; | 184 value = &header[i].value; |
182 ip = header[i].value.data; | 185 xfwd = NULL; |
183 | 186 |
184 goto found; | 187 goto found; |
185 } | 188 } |
186 } | 189 } |
187 | 190 |
190 | 193 |
191 found: | 194 found: |
192 | 195 |
193 c = r->connection; | 196 c = r->connection; |
194 | 197 |
195 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); | |
196 | |
197 addr.sockaddr = c->sockaddr; | 198 addr.sockaddr = c->sockaddr; |
198 addr.socklen = c->socklen; | 199 addr.socklen = c->socklen; |
199 /* addr.name = c->addr_text; */ | 200 /* addr.name = c->addr_text; */ |
200 | 201 |
201 if (ngx_http_get_forwarded_addr(r, &addr, ip, len, rlcf->from, | 202 if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from, |
202 rlcf->recursive) | 203 rlcf->recursive) |
203 == NGX_OK) | 204 != NGX_DECLINED) |
204 { | 205 { |
205 return ngx_http_realip_set_addr(r, &addr); | 206 return ngx_http_realip_set_addr(r, &addr); |
206 } | 207 } |
207 | 208 |
208 return NGX_DECLINED; | 209 return NGX_DECLINED; |