Mercurial > hg > nginx
comparison src/http/modules/ngx_http_proxy_module.c @ 4462:a73c63bdce32
Proxy: generic rewrite code from the "proxy_redirect" handlers moved to a
separate function with trivial optimization.
No functional changes.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Mon, 13 Feb 2012 10:56:09 +0000 |
parents | 103587c7ae5f |
children | a068ec122f17 |
comparison
equal
deleted
inserted
replaced
4461:103587c7ae5f | 4462:a73c63bdce32 |
---|---|
11 | 11 |
12 | 12 |
13 typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t; | 13 typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t; |
14 | 14 |
15 typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r, | 15 typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r, |
16 ngx_table_elt_t *h, size_t prefix, ngx_http_proxy_rewrite_t *pr); | 16 ngx_table_elt_t *h, size_t prefix, size_t len, |
17 ngx_http_proxy_rewrite_t *pr); | |
17 | 18 |
18 struct ngx_http_proxy_rewrite_s { | 19 struct ngx_http_proxy_rewrite_s { |
19 ngx_http_proxy_rewrite_pt handler; | 20 ngx_http_proxy_rewrite_pt handler; |
20 | 21 |
21 union { | 22 union { |
121 static ngx_int_t | 122 static ngx_int_t |
122 ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, | 123 ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, |
123 ngx_http_variable_value_t *v, uintptr_t data); | 124 ngx_http_variable_value_t *v, uintptr_t data); |
124 static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, | 125 static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, |
125 ngx_table_elt_t *h, size_t prefix); | 126 ngx_table_elt_t *h, size_t prefix); |
127 static ngx_int_t ngx_http_proxy_rewrite(ngx_http_request_t *r, | |
128 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_str_t *replacement); | |
126 | 129 |
127 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); | 130 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); |
128 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); | 131 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); |
129 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, | 132 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, |
130 void *parent, void *child); | 133 void *parent, void *child); |
2270 | 2273 |
2271 static ngx_int_t | 2274 static ngx_int_t |
2272 ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h, | 2275 ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h, |
2273 size_t prefix) | 2276 size_t prefix) |
2274 { | 2277 { |
2278 size_t len; | |
2275 ngx_int_t rc; | 2279 ngx_int_t rc; |
2276 ngx_uint_t i; | 2280 ngx_uint_t i; |
2277 ngx_http_proxy_rewrite_t *pr; | 2281 ngx_http_proxy_rewrite_t *pr; |
2278 ngx_http_proxy_loc_conf_t *plcf; | 2282 ngx_http_proxy_loc_conf_t *plcf; |
2279 | 2283 |
2283 | 2287 |
2284 if (pr == NULL) { | 2288 if (pr == NULL) { |
2285 return NGX_DECLINED; | 2289 return NGX_DECLINED; |
2286 } | 2290 } |
2287 | 2291 |
2292 len = h->value.len - prefix; | |
2293 | |
2288 for (i = 0; i < plcf->redirects->nelts; i++) { | 2294 for (i = 0; i < plcf->redirects->nelts; i++) { |
2289 rc = pr[i].handler(r, h, prefix, &pr[i]); | 2295 rc = pr[i].handler(r, h, prefix, len, &pr[i]); |
2290 | 2296 |
2291 if (rc != NGX_DECLINED) { | 2297 if (rc != NGX_DECLINED) { |
2292 return rc; | 2298 return rc; |
2293 } | 2299 } |
2294 } | 2300 } |
2297 } | 2303 } |
2298 | 2304 |
2299 | 2305 |
2300 static ngx_int_t | 2306 static ngx_int_t |
2301 ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r, | 2307 ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r, |
2302 ngx_table_elt_t *h, size_t prefix, ngx_http_proxy_rewrite_t *pr) | 2308 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) |
2303 { | 2309 { |
2304 size_t len; | 2310 ngx_str_t pattern, replacement; |
2305 u_char *data, *p; | |
2306 ngx_str_t pattern, replacement; | |
2307 | 2311 |
2308 if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) { | 2312 if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) { |
2309 return NGX_ERROR; | 2313 return NGX_ERROR; |
2310 } | 2314 } |
2311 | 2315 |
2312 if (pattern.len > h->value.len - prefix | 2316 if (pattern.len > len |
2313 || ngx_rstrncmp(h->value.data + prefix, pattern.data, | 2317 || ngx_rstrncmp(h->value.data + prefix, pattern.data, |
2314 pattern.len) != 0) | 2318 pattern.len) != 0) |
2315 { | 2319 { |
2316 return NGX_DECLINED; | 2320 return NGX_DECLINED; |
2317 } | 2321 } |
2318 | 2322 |
2319 if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { | 2323 if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { |
2320 return NGX_ERROR; | 2324 return NGX_ERROR; |
2321 } | 2325 } |
2322 | 2326 |
2323 len = replacement.len + h->value.len - pattern.len; | 2327 return ngx_http_proxy_rewrite(r, h, prefix, pattern.len, &replacement); |
2324 | 2328 } |
2325 data = ngx_pnalloc(r->pool, len); | 2329 |
2326 if (data == NULL) { | 2330 |
2331 #if (NGX_PCRE) | |
2332 | |
2333 static ngx_int_t | |
2334 ngx_http_proxy_rewrite_regex_handler(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2335 size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) | |
2336 { | |
2337 ngx_str_t pattern, replacement; | |
2338 | |
2339 pattern.len = len; | |
2340 pattern.data = h->value.data + prefix; | |
2341 | |
2342 if (ngx_http_regex_exec(r, pr->pattern.regex, &pattern) != NGX_OK) { | |
2343 return NGX_DECLINED; | |
2344 } | |
2345 | |
2346 if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { | |
2327 return NGX_ERROR; | 2347 return NGX_ERROR; |
2328 } | 2348 } |
2329 | 2349 |
2330 p = ngx_copy(data, h->value.data, prefix); | 2350 if (prefix == 0 && h->value.len == len) { |
2331 | 2351 h->value = replacement; |
2332 if (replacement.len) { | 2352 return NGX_OK; |
2333 p = ngx_copy(p, replacement.data, replacement.len); | 2353 } |
2334 } | 2354 |
2335 | 2355 return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement); |
2336 ngx_memcpy(p, h->value.data + prefix + pattern.len, | 2356 } |
2337 h->value.len - pattern.len - prefix); | 2357 |
2338 | 2358 #endif |
2339 h->value.len = len; | 2359 |
2340 h->value.data = data; | 2360 |
2361 static ngx_int_t | |
2362 ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix, | |
2363 size_t len, ngx_str_t *replacement) | |
2364 { | |
2365 u_char *p, *data; | |
2366 size_t new_len; | |
2367 | |
2368 new_len = replacement->len + h->value.len - len; | |
2369 | |
2370 if (replacement->len > len) { | |
2371 | |
2372 data = ngx_pnalloc(r->pool, new_len); | |
2373 if (data == NULL) { | |
2374 return NGX_ERROR; | |
2375 } | |
2376 | |
2377 p = ngx_copy(data, h->value.data, prefix); | |
2378 p = ngx_copy(p, replacement->data, replacement->len); | |
2379 | |
2380 ngx_memcpy(p, h->value.data + prefix + len, | |
2381 h->value.len - len - prefix); | |
2382 | |
2383 h->value.data = data; | |
2384 | |
2385 } else { | |
2386 p = ngx_copy(h->value.data + prefix, replacement->data, | |
2387 replacement->len); | |
2388 | |
2389 ngx_memmove(p, h->value.data + prefix + len, | |
2390 h->value.len - len - prefix); | |
2391 } | |
2392 | |
2393 h->value.len = new_len; | |
2341 | 2394 |
2342 return NGX_OK; | 2395 return NGX_OK; |
2343 } | 2396 } |
2344 | |
2345 | |
2346 #if (NGX_PCRE) | |
2347 | |
2348 static ngx_int_t | |
2349 ngx_http_proxy_rewrite_regex_handler(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2350 size_t prefix, ngx_http_proxy_rewrite_t *pr) | |
2351 { | |
2352 size_t len; | |
2353 u_char *data; | |
2354 ngx_str_t pattern, replacement; | |
2355 | |
2356 pattern.len = h->value.len - prefix; | |
2357 pattern.data = h->value.data + prefix; | |
2358 | |
2359 if (ngx_http_regex_exec(r, pr->pattern.regex, &pattern) != NGX_OK) { | |
2360 return NGX_DECLINED; | |
2361 } | |
2362 | |
2363 if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { | |
2364 return NGX_ERROR; | |
2365 } | |
2366 | |
2367 if (!prefix) { | |
2368 h->value = replacement; | |
2369 return NGX_OK; | |
2370 } | |
2371 | |
2372 len = prefix + replacement.len; | |
2373 | |
2374 data = ngx_pnalloc(r->pool, len); | |
2375 if (data == NULL) { | |
2376 return NGX_ERROR; | |
2377 } | |
2378 | |
2379 ngx_memcpy(data, h->value.data, prefix); | |
2380 ngx_memcpy(data + prefix, replacement.data, replacement.len); | |
2381 | |
2382 h->value.len = len; | |
2383 h->value.data = data; | |
2384 | |
2385 return NGX_OK; | |
2386 } | |
2387 | |
2388 #endif | |
2389 | 2397 |
2390 | 2398 |
2391 static ngx_int_t | 2399 static ngx_int_t |
2392 ngx_http_proxy_add_variables(ngx_conf_t *cf) | 2400 ngx_http_proxy_add_variables(ngx_conf_t *cf) |
2393 { | 2401 { |