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 {