comparison src/http/modules/ngx_http_proxy_module.c @ 4927:93294110728f

Request body: always use calculated size of a request body in proxy. This allows to handle requests with chunked body, and also simplifies handling of various request body modifications.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 21 Nov 2012 01:03:48 +0000
parents 32030fa8cb14
children 4251e72b8bb4
comparison
equal deleted inserted replaced
4926:1c9d8b6523c0 4927:93294110728f
81 81
82 typedef struct { 82 typedef struct {
83 ngx_http_status_t status; 83 ngx_http_status_t status;
84 ngx_http_chunked_t chunked; 84 ngx_http_chunked_t chunked;
85 ngx_http_proxy_vars_t vars; 85 ngx_http_proxy_vars_t vars;
86 size_t internal_body_length; 86 off_t internal_body_length;
87 87
88 ngx_uint_t head; /* unsigned head:1 */ 88 ngx_uint_t head; /* unsigned head:1 */
89 } ngx_http_proxy_ctx_t; 89 } ngx_http_proxy_ctx_t;
90 90
91 91
553 553
554 554
555 static ngx_keyval_t ngx_http_proxy_headers[] = { 555 static ngx_keyval_t ngx_http_proxy_headers[] = {
556 { ngx_string("Host"), ngx_string("$proxy_host") }, 556 { ngx_string("Host"), ngx_string("$proxy_host") },
557 { ngx_string("Connection"), ngx_string("close") }, 557 { ngx_string("Connection"), ngx_string("close") },
558 { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
559 { ngx_string("Transfer-Encoding"), ngx_string("") },
558 { ngx_string("Keep-Alive"), ngx_string("") }, 560 { ngx_string("Keep-Alive"), ngx_string("") },
559 { ngx_string("Expect"), ngx_string("") }, 561 { ngx_string("Expect"), ngx_string("") },
560 { ngx_string("Upgrade"), ngx_string("") }, 562 { ngx_string("Upgrade"), ngx_string("") },
561 { ngx_null_string, ngx_null_string } 563 { ngx_null_string, ngx_null_string }
562 }; 564 };
578 #if (NGX_HTTP_CACHE) 580 #if (NGX_HTTP_CACHE)
579 581
580 static ngx_keyval_t ngx_http_proxy_cache_headers[] = { 582 static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
581 { ngx_string("Host"), ngx_string("$proxy_host") }, 583 { ngx_string("Host"), ngx_string("$proxy_host") },
582 { ngx_string("Connection"), ngx_string("close") }, 584 { ngx_string("Connection"), ngx_string("close") },
585 { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
586 { ngx_string("Transfer-Encoding"), ngx_string("") },
583 { ngx_string("Keep-Alive"), ngx_string("") }, 587 { ngx_string("Keep-Alive"), ngx_string("") },
584 { ngx_string("Expect"), ngx_string("") }, 588 { ngx_string("Expect"), ngx_string("") },
585 { ngx_string("Upgrade"), ngx_string("") }, 589 { ngx_string("Upgrade"), ngx_string("") },
586 { ngx_string("If-Modified-Since"), ngx_string("") }, 590 { ngx_string("If-Modified-Since"), ngx_string("") },
587 { ngx_string("If-Unmodified-Since"), ngx_string("") }, 591 { ngx_string("If-Unmodified-Since"), ngx_string("") },
1001 body_len += lcode(&le); 1005 body_len += lcode(&le);
1002 } 1006 }
1003 1007
1004 ctx->internal_body_length = body_len; 1008 ctx->internal_body_length = body_len;
1005 len += body_len; 1009 len += body_len;
1010
1011 } else {
1012 ctx->internal_body_length = r->headers_in.content_length_n;
1006 } 1013 }
1007 1014
1008 le.ip = plcf->headers_set_len->elts; 1015 le.ip = plcf->headers_set_len->elts;
1009 le.request = r; 1016 le.request = r;
1010 le.flushed = 1; 1017 le.flushed = 1;
2037 { 2044 {
2038 ngx_http_proxy_ctx_t *ctx; 2045 ngx_http_proxy_ctx_t *ctx;
2039 2046
2040 ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); 2047 ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
2041 2048
2042 if (ctx == NULL) { 2049 if (ctx == NULL || ctx->internal_body_length < 0) {
2043 v->not_found = 1; 2050 v->not_found = 1;
2044 return NGX_OK; 2051 return NGX_OK;
2045 } 2052 }
2046 2053
2047 v->valid = 1; 2054 v->valid = 1;
2048 v->no_cacheable = 0; 2055 v->no_cacheable = 0;
2049 v->not_found = 0; 2056 v->not_found = 0;
2050 2057
2051 v->data = ngx_pnalloc(r->connection->pool, NGX_SIZE_T_LEN); 2058 v->data = ngx_pnalloc(r->connection->pool, NGX_OFF_T_LEN);
2052 2059
2053 if (v->data == NULL) { 2060 if (v->data == NULL) {
2054 return NGX_ERROR; 2061 return NGX_ERROR;
2055 } 2062 }
2056 2063
2057 v->len = ngx_sprintf(v->data, "%uz", ctx->internal_body_length) - v->data; 2064 v->len = ngx_sprintf(v->data, "%O", ctx->internal_body_length) - v->data;
2058 2065
2059 return NGX_OK; 2066 return NGX_OK;
2060 } 2067 }
2061 2068
2062 2069
2820 conf->headers_set_hash = prev->headers_set_hash; 2827 conf->headers_set_hash = prev->headers_set_hash;
2821 conf->headers_source = prev->headers_source; 2828 conf->headers_source = prev->headers_source;
2822 } 2829 }
2823 2830
2824 if (conf->headers_set_hash.buckets 2831 if (conf->headers_set_hash.buckets
2825 && ((conf->body_source.data == NULL)
2826 == (prev->body_source.data == NULL))
2827 #if (NGX_HTTP_CACHE) 2832 #if (NGX_HTTP_CACHE)
2828 && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) 2833 && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
2829 #endif 2834 #endif
2830 ) 2835 )
2831 { 2836 {
2902 *s = *h; 2907 *s = *h;
2903 2908
2904 next: 2909 next:
2905 2910
2906 h++; 2911 h++;
2907 }
2908
2909 if (conf->body_source.data) {
2910 s = ngx_array_push(&headers_merged);
2911 if (s == NULL) {
2912 return NGX_ERROR;
2913 }
2914
2915 ngx_str_set(&s->key, "Content-Length");
2916 ngx_str_set(&s->value, "$proxy_internal_body_length");
2917 } 2912 }
2918 2913
2919 2914
2920 src = headers_merged.elts; 2915 src = headers_merged.elts;
2921 for (i = 0; i < headers_merged.nelts; i++) { 2916 for (i = 0; i < headers_merged.nelts; i++) {