Klaus Demo nginx / 7ef115a
Upstream: trailers support, u->conf->pass_trailers flag. Basic trailer headers support allows one to access response trailers via the $upstream_trailer_* variables. Additionally, the u->conf->pass_trailers flag was introduced. When the flag is set, trailer headers from the upstream response are passed to the client. Like normal headers, trailer headers will be hidden if present in u->conf->hide_headers_hash. Maxim Dounin 2 years ago
2 changed file(s) with 98 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
5353 ngx_http_upstream_t *u);
5454 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
5555 static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
56 ngx_http_upstream_t *u);
57 static ngx_int_t ngx_http_upstream_process_trailers(ngx_http_request_t *r,
5658 ngx_http_upstream_t *u);
5759 static void ngx_http_upstream_send_response(ngx_http_request_t *r,
5860 ngx_http_upstream_t *u);
163165 ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
164166 static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
165167 ngx_http_variable_value_t *v, uintptr_t data);
168 static ngx_int_t ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
169 ngx_http_variable_value_t *v, uintptr_t data);
166170 static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
167171 ngx_http_variable_value_t *v, uintptr_t data);
168172
422426 { ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_variable,
423427 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
424428
429 { ngx_string("upstream_trailer_"), NULL, ngx_http_upstream_trailer_variable,
430 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
431
425432 { ngx_string("upstream_cookie_"), NULL, ngx_http_upstream_cookie_variable,
426433 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
427434
10451052 return NGX_ERROR;
10461053 }
10471054
1055 if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
1056 sizeof(ngx_table_elt_t))
1057 != NGX_OK)
1058 {
1059 return NGX_ERROR;
1060 }
1061
10481062 rc = u->process_header(r);
10491063
10501064 if (rc == NGX_OK) {
18821896 return NGX_ERROR;
18831897 }
18841898
1899 if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
1900 sizeof(ngx_table_elt_t))
1901 != NGX_OK)
1902 {
1903 return NGX_ERROR;
1904 }
1905
18851906 /* reinit the request chain */
18861907
18871908 file_pos = 0;
22362257 return;
22372258 }
22382259
2260 if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
2261 sizeof(ngx_table_elt_t))
2262 != NGX_OK)
2263 {
2264 ngx_http_upstream_finalize_request(r, u,
2265 NGX_HTTP_INTERNAL_SERVER_ERROR);
2266 return;
2267 }
2268
22392269 #if (NGX_HTTP_CACHE)
22402270
22412271 if (r->cache) {
27292759 }
27302760
27312761 u->length = -1;
2762
2763 return NGX_OK;
2764 }
2765
2766
2767 static ngx_int_t
2768 ngx_http_upstream_process_trailers(ngx_http_request_t *r,
2769 ngx_http_upstream_t *u)
2770 {
2771 ngx_uint_t i;
2772 ngx_list_part_t *part;
2773 ngx_table_elt_t *h, *ho;
2774
2775 if (!u->conf->pass_trailers) {
2776 return NGX_OK;
2777 }
2778
2779 part = &u->headers_in.trailers.part;
2780 h = part->elts;
2781
2782 for (i = 0; /* void */; i++) {
2783
2784 if (i >= part->nelts) {
2785 if (part->next == NULL) {
2786 break;
2787 }
2788
2789 part = part->next;
2790 h = part->elts;
2791 i = 0;
2792 }
2793
2794 if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash,
2795 h[i].lowcase_key, h[i].key.len))
2796 {
2797 continue;
2798 }
2799
2800 ho = ngx_list_push(&r->headers_out.trailers);
2801 if (ho == NULL) {
2802 return NGX_ERROR;
2803 }
2804
2805 *ho = h[i];
2806 }
27322807
27332808 return NGX_OK;
27342809 }
42714346 }
42724347
42734348 if (rc == 0) {
4349
4350 if (ngx_http_upstream_process_trailers(r, u) != NGX_OK) {
4351 ngx_http_finalize_request(r, NGX_ERROR);
4352 return;
4353 }
4354
42744355 rc = ngx_http_send_special(r, NGX_HTTP_LAST);
42754356
42764357 } else if (flush) {
53775458 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
53785459 &r->upstream->headers_in.headers.part,
53795460 sizeof("upstream_http_") - 1);
5461 }
5462
5463
5464 static ngx_int_t
5465 ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
5466 ngx_http_variable_value_t *v, uintptr_t data)
5467 {
5468 if (r->upstream == NULL) {
5469 v->not_found = 1;
5470 return NGX_OK;
5471 }
5472
5473 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
5474 &r->upstream->headers_in.trailers.part,
5475 sizeof("upstream_trailer_") - 1);
53805476 }
53815477
53825478
221221 signed store:2;
222222 unsigned intercept_404:1;
223223 unsigned change_buffering:1;
224 unsigned pass_trailers:1;
224225
225226 #if (NGX_HTTP_SSL || NGX_COMPAT)
226227 ngx_ssl_t *ssl;
250251
251252 typedef struct {
252253 ngx_list_t headers;
254 ngx_list_t trailers;
253255
254256 ngx_uint_t status_n;
255257 ngx_str_t status_line;