Mercurial > hg > nginx
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++) { |