annotate src/http/v2/ngx_http_v2_filter_module.c @ 9218:de4208483315

HTTP/2: fixed incorrect name slipped in 9213:23f109f0facc.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 20 Feb 2024 19:28:26 +0300
parents 23f109f0facc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3 * Copyright (C) Nginx, Inc.
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4 * Copyright (C) Valentin V. Bartenev
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
5 * Copyright (C) Ruslan Ermilov
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
6 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
7
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
9 #include <ngx_config.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
10 #include <ngx_core.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
11 #include <ngx_http.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
12 #include <nginx.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
13 #include <ngx_http_v2_module.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
14
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
15
6279
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
16 /*
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
17 * This returns precise number of octets for values in range 0..253
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
18 * and estimate number for the rest, but not smaller than required.
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
19 */
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
20
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
21 #define ngx_http_v2_integer_octets(v) (1 + (v) / 127)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
22
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
23 #define ngx_http_v2_literal_size(h) \
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
24 (ngx_http_v2_integer_octets(sizeof(h) - 1) + sizeof(h) - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
25
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
26
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
27 #define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
28
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
29
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
30 static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
31 ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
32 static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
33 ngx_http_request_t *r);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
34
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
35 static ngx_chain_t *ngx_http_v2_send_chain(ngx_connection_t *fc,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
36 ngx_chain_t *in, off_t limit);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
37
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
38 static ngx_chain_t *ngx_http_v2_filter_get_shadow(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
39 ngx_http_v2_stream_t *stream, ngx_buf_t *buf, off_t offset, off_t size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
40 static ngx_http_v2_out_frame_t *ngx_http_v2_filter_get_data_frame(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
41 ngx_http_v2_stream_t *stream, size_t len, ngx_chain_t *first,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
42 ngx_chain_t *last);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
43
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
44 static ngx_inline ngx_int_t ngx_http_v2_flow_control(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
45 ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
46 static void ngx_http_v2_waiting_queue(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
47 ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
48
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
49 static ngx_inline ngx_int_t ngx_http_v2_filter_send(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
50 ngx_connection_t *fc, ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
51
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
52 static ngx_int_t ngx_http_v2_headers_frame_handler(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
53 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
54 static ngx_int_t ngx_http_v2_data_frame_handler(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
55 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
56 static ngx_inline void ngx_http_v2_handle_frame(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
57 ngx_http_v2_stream_t *stream, ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
58 static ngx_inline void ngx_http_v2_handle_stream(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
59 ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
60
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
61 static void ngx_http_v2_filter_cleanup(void *data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
62
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
63 static ngx_int_t ngx_http_v2_filter_init(ngx_conf_t *cf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
64
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
65
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
66 static ngx_http_module_t ngx_http_v2_filter_module_ctx = {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
67 NULL, /* preconfiguration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
68 ngx_http_v2_filter_init, /* postconfiguration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
69
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
70 NULL, /* create main configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
71 NULL, /* init main configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
72
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
73 NULL, /* create server configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
74 NULL, /* merge server configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
75
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
76 NULL, /* create location configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
77 NULL /* merge location configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
78 };
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
79
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
80
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
81 ngx_module_t ngx_http_v2_filter_module = {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
82 NGX_MODULE_V1,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
83 &ngx_http_v2_filter_module_ctx, /* module context */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
84 NULL, /* module directives */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
85 NGX_HTTP_MODULE, /* module type */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
86 NULL, /* init master */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
87 NULL, /* init module */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
88 NULL, /* init process */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
89 NULL, /* init thread */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
90 NULL, /* exit thread */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
91 NULL, /* exit process */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
92 NULL, /* exit master */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
93 NGX_MODULE_V1_PADDING
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
94 };
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
95
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
96
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
97 static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
98
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
99
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
100 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
101 ngx_http_v2_header_filter(ngx_http_request_t *r)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
102 {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
103 u_char status, *pos, *start, *p, *tmp;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
104 size_t len, tmp_len;
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
105 ngx_str_t host, location;
7235
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
106 ngx_uint_t i, port, fin;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
107 ngx_list_part_t *part;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
108 ngx_table_elt_t *header;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
109 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
110 ngx_http_cleanup_t *cln;
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
111 ngx_http_v2_stream_t *stream;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
112 ngx_http_v2_out_frame_t *frame;
7100
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
113 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
114 ngx_http_core_loc_conf_t *clcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
115 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
116 u_char addr[NGX_SOCKADDR_STRLEN];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
117
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
118 #if (NGX_HTTP_GZIP)
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
119 static const u_char accept_encoding[12] =
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
120 "\x8b\x84\x84\x2d\x69\x5b\x05\x44\x3c\x86\xaa\x6f";
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
121 #endif
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
122
9213
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
123 static size_t nginx_name_len = ngx_http_v2_literal_size(NGINX_NAME);
9218
de4208483315 HTTP/2: fixed incorrect name slipped in 9213:23f109f0facc.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9213
diff changeset
124 static u_char nginx_name[ngx_http_v2_literal_size(NGINX_NAME)];
9213
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
125
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
126 static size_t nginx_ver_len = ngx_http_v2_literal_size(NGINX_VER);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
127 static u_char nginx_ver[ngx_http_v2_literal_size(NGINX_VER)];
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
128
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
129 static size_t nginx_ver_build_len =
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
130 ngx_http_v2_literal_size(NGINX_VER_BUILD);
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
131 static u_char nginx_ver_build[ngx_http_v2_literal_size(NGINX_VER_BUILD)];
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
132
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
133 stream = r->stream;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
134
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
135 if (!stream) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
136 return ngx_http_next_header_filter(r);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
137 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
138
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
139 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
140 "http2 header filter");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
141
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
142 if (r->header_sent) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
143 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
144 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
145
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
146 r->header_sent = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
147
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
148 if (r != r->main) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
149 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
150 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
151
6637
699e409a3e0c HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents: 6600
diff changeset
152 fc = r->connection;
699e409a3e0c HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents: 6600
diff changeset
153
699e409a3e0c HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents: 6600
diff changeset
154 if (fc->error) {
699e409a3e0c HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents: 6600
diff changeset
155 return NGX_ERROR;
699e409a3e0c HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents: 6600
diff changeset
156 }
699e409a3e0c HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents: 6600
diff changeset
157
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
158 if (r->method == NGX_HTTP_HEAD) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
159 r->header_only = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
160 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
161
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
162 switch (r->headers_out.status) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
163
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
164 case NGX_HTTP_OK:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
165 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_200_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
166 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
167
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
168 case NGX_HTTP_NO_CONTENT:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
169 r->header_only = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
170
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
171 ngx_str_null(&r->headers_out.content_type);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
172
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
173 r->headers_out.content_length = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
174 r->headers_out.content_length_n = -1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
175
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
176 r->headers_out.last_modified_time = -1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
177 r->headers_out.last_modified = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
178
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
179 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_204_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
180 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
181
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
182 case NGX_HTTP_PARTIAL_CONTENT:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
183 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_206_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
184 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
185
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
186 case NGX_HTTP_NOT_MODIFIED:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
187 r->header_only = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
188 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_304_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
189 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
190
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
191 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
192 r->headers_out.last_modified_time = -1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
193 r->headers_out.last_modified = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
194
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
195 switch (r->headers_out.status) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
196
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
197 case NGX_HTTP_BAD_REQUEST:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
198 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_400_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
199 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
200
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
201 case NGX_HTTP_NOT_FOUND:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
202 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_404_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
203 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
204
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
205 case NGX_HTTP_INTERNAL_SERVER_ERROR:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
206 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_500_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
207 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
208
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
209 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
210 status = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
211 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
212 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
213
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
214 h2c = stream->connection;
7100
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
215
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
216 len = h2c->table_update ? 1 : 0;
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
217
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
218 len += status ? 1 : 1 + ngx_http_v2_literal_size("418");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
219
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
220 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
221
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
222 if (r->headers_out.server == NULL) {
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
223
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
224 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
225 len += 1 + nginx_ver_len;
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
226
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
227 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
228 len += 1 + nginx_ver_build_len;
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
229
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
230 } else {
9213
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
231 len += 1 + nginx_name_len;
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
232 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
233 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
234
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
235 if (r->headers_out.date == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
236 len += 1 + ngx_http_v2_literal_size("Wed, 31 Dec 1986 18:00:00 GMT");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
237 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
238
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
239 if (r->headers_out.content_type.len) {
6274
b2de4a56b860 HTTP/2: fixed header block size calculation.
Valentin Bartenev <vbart@nginx.com>
parents: 6251
diff changeset
240 len += 1 + NGX_HTTP_V2_INT_OCTETS + r->headers_out.content_type.len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
241
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
242 if (r->headers_out.content_type_len == r->headers_out.content_type.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
243 && r->headers_out.charset.len)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
244 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
245 len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
246 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
247 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
248
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
249 if (r->headers_out.content_length == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
250 && r->headers_out.content_length_n >= 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
251 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
252 len += 1 + ngx_http_v2_integer_octets(NGX_OFF_T_LEN) + NGX_OFF_T_LEN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
253 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
254
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
255 if (r->headers_out.last_modified == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
256 && r->headers_out.last_modified_time != -1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
257 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
258 len += 1 + ngx_http_v2_literal_size("Wed, 31 Dec 1986 18:00:00 GMT");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
259 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
260
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
261 if (r->headers_out.location && r->headers_out.location->value.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
262
6852
d15172ebb400 Core: relative redirects (closes #1000).
Ruslan Ermilov <ru@nginx.com>
parents: 6833
diff changeset
263 if (r->headers_out.location->value.data[0] == '/'
d15172ebb400 Core: relative redirects (closes #1000).
Ruslan Ermilov <ru@nginx.com>
parents: 6833
diff changeset
264 && clcf->absolute_redirect)
d15172ebb400 Core: relative redirects (closes #1000).
Ruslan Ermilov <ru@nginx.com>
parents: 6833
diff changeset
265 {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
266 if (clcf->server_name_in_redirect) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
267 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
268 host = cscf->server_name;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
269
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
270 } else if (r->headers_in.server.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
271 host = r->headers_in.server;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
272
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
273 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
274 host.len = NGX_SOCKADDR_STRLEN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
275 host.data = addr;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
276
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
277 if (ngx_connection_local_sockaddr(fc, &host, 0) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
278 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
279 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
280 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
281
6593
b3b7e33083ac Introduced ngx_inet_get_port() and ngx_inet_set_port() functions.
Roman Arutyunyan <arut@nginx.com>
parents: 6451
diff changeset
282 port = ngx_inet_get_port(fc->local_sockaddr);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
283
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
284 location.len = sizeof("https://") - 1 + host.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
285 + r->headers_out.location->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
286
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
287 if (clcf->port_in_redirect) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
288
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
289 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
290 if (fc->ssl)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
291 port = (port == 443) ? 0 : port;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
292 else
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
293 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
294 port = (port == 80) ? 0 : port;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
295
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
296 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
297 port = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
298 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
299
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
300 if (port) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
301 location.len += sizeof(":65535") - 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
302 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
303
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
304 location.data = ngx_pnalloc(r->pool, location.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
305 if (location.data == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
306 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
307 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
308
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
309 p = ngx_cpymem(location.data, "http", sizeof("http") - 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
310
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
311 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
312 if (fc->ssl) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
313 *p++ = 's';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
314 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
315 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
316
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
317 *p++ = ':'; *p++ = '/'; *p++ = '/';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
318 p = ngx_cpymem(p, host.data, host.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
319
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
320 if (port) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
321 p = ngx_sprintf(p, ":%ui", port);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
322 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
323
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
324 p = ngx_cpymem(p, r->headers_out.location->value.data,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
325 r->headers_out.location->value.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
326
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
327 /* update r->headers_out.location->value for possible logging */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
328
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
329 r->headers_out.location->value.len = p - location.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
330 r->headers_out.location->value.data = location.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
331 ngx_str_set(&r->headers_out.location->key, "Location");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
332 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
333
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
334 r->headers_out.location->hash = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
335
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
336 len += 1 + NGX_HTTP_V2_INT_OCTETS + r->headers_out.location->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
337 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
338
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
339 tmp_len = len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
340
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
341 #if (NGX_HTTP_GZIP)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
342 if (r->gzip_vary) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
343 if (clcf->gzip_vary) {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
344 len += 1 + sizeof(accept_encoding);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
345
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
346 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
347 r->gzip_vary = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
348 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
349 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
350 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
351
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
352 part = &r->headers_out.headers.part;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
353 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
354
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
355 for (i = 0; /* void */; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
356
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
357 if (i >= part->nelts) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
358 if (part->next == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
359 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
360 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
361
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
362 part = part->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
363 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
364 i = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
365 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
366
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
367 if (header[i].hash == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
368 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
369 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
370
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
371 if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) {
6400
b4c28876d2c3 HTTP/2: use local pointer instead of r->connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6395
diff changeset
372 ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
373 "too long response header name: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
374 &header[i].key);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
375 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
376 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
377
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
378 if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) {
6400
b4c28876d2c3 HTTP/2: use local pointer instead of r->connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6395
diff changeset
379 ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
380 "too long response header value: \"%V: %V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
381 &header[i].key, &header[i].value);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
382 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
383 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
384
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
385 len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
386 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len;
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
387
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
388 if (header[i].key.len > tmp_len) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
389 tmp_len = header[i].key.len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
390 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
391
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
392 if (header[i].value.len > tmp_len) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
393 tmp_len = header[i].value.len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
394 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
395 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
396
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
397 tmp = ngx_palloc(r->pool, tmp_len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
398 pos = ngx_pnalloc(r->pool, len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
399
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
400 if (pos == NULL || tmp == NULL) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
401 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
402 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
403
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
404 start = pos;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
405
7100
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
406 if (h2c->table_update) {
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
407 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
408 "http2 table size update: 0");
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
409 *pos++ = (1 << 5) | 0;
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
410 h2c->table_update = 0;
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
411 }
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7035
diff changeset
412
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
413 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
414 "http2 output header: \":status: %03ui\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
415 r->headers_out.status);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
416
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
417 if (status) {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
418 *pos++ = status;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
419
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
420 } else {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
421 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_STATUS_INDEX);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
422 *pos++ = NGX_HTTP_V2_ENCODE_RAW | 3;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
423 pos = ngx_sprintf(pos, "%03ui", r->headers_out.status);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
424 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
425
6449
e5076b96fd01 Reconsidered server_tokens with an empty value.
Ruslan Ermilov <ru@nginx.com>
parents: 6434
diff changeset
426 if (r->headers_out.server == NULL) {
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
427
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
428 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
429 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
430 "http2 output header: \"server: %s\"",
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
431 NGINX_VER);
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
432
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
433 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
434 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
435 "http2 output header: \"server: %s\"",
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
436 NGINX_VER_BUILD);
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
437
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
438 } else {
9213
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
439 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
440 "http2 output header: \"server: %s\"",
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
441 NGINX_NAME);
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
442 }
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
443
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
444 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
445
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
446 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
447 if (nginx_ver[0] == '\0') {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
448 p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
449 sizeof(NGINX_VER) - 1, tmp);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
450 nginx_ver_len = p - nginx_ver;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
451 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
452
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
453 pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len);
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
454
6885
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
455 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
456 if (nginx_ver_build[0] == '\0') {
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
457 p = ngx_http_v2_write_value(nginx_ver_build,
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
458 (u_char *) NGINX_VER_BUILD,
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
459 sizeof(NGINX_VER_BUILD) - 1, tmp);
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
460 nginx_ver_build_len = p - nginx_ver_build;
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
461 }
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
462
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
463 pos = ngx_cpymem(pos, nginx_ver_build, nginx_ver_build_len);
25203fc377fb Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents: 6852
diff changeset
464
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
465 } else {
9213
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
466 if (nginx_name[0] == '\0') {
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
467 p = ngx_http_v2_write_value(nginx_name, (u_char *) NGINX_NAME,
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
468 sizeof(NGINX_NAME) - 1, tmp);
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
469 nginx_name_len = p - nginx_name;
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
470 }
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
471
23f109f0facc Free nginx: changed server name.
Maxim Dounin <mdounin@mdounin.ru>
parents: 9121
diff changeset
472 pos = ngx_cpymem(pos, nginx_name, nginx_name_len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
473 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
474 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
475
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
476 if (r->headers_out.date == NULL) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
477 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
478 "http2 output header: \"date: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
479 &ngx_cached_http_time);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
480
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
481 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_DATE_INDEX);
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
482 pos = ngx_http_v2_write_value(pos, ngx_cached_http_time.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
483 ngx_cached_http_time.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
484 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
485
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
486 if (r->headers_out.content_type.len) {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
487 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_CONTENT_TYPE_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
488
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
489 if (r->headers_out.content_type_len == r->headers_out.content_type.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
490 && r->headers_out.charset.len)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
491 {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
492 len = r->headers_out.content_type.len + sizeof("; charset=") - 1
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
493 + r->headers_out.charset.len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
494
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
495 p = ngx_pnalloc(r->pool, len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
496 if (p == NULL) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
497 return NGX_ERROR;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
498 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
499
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
500 p = ngx_cpymem(p, r->headers_out.content_type.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
501 r->headers_out.content_type.len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
502
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
503 p = ngx_cpymem(p, "; charset=", sizeof("; charset=") - 1);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
504
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
505 p = ngx_cpymem(p, r->headers_out.charset.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
506 r->headers_out.charset.len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
507
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
508 /* updated r->headers_out.content_type is also needed for logging */
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
509
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
510 r->headers_out.content_type.len = len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
511 r->headers_out.content_type.data = p - len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
512 }
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
513
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
514 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
515 "http2 output header: \"content-type: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
516 &r->headers_out.content_type);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
517
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
518 pos = ngx_http_v2_write_value(pos, r->headers_out.content_type.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
519 r->headers_out.content_type.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
520 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
521
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
522 if (r->headers_out.content_length == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
523 && r->headers_out.content_length_n >= 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
524 {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
525 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
526 "http2 output header: \"content-length: %O\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
527 r->headers_out.content_length_n);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
528
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
529 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_CONTENT_LENGTH_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
530
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
531 p = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
532 pos = ngx_sprintf(pos + 1, "%O", r->headers_out.content_length_n);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
533 *p = NGX_HTTP_V2_ENCODE_RAW | (u_char) (pos - p - 1);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
534 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
535
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
536 if (r->headers_out.last_modified == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
537 && r->headers_out.last_modified_time != -1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
538 {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
539 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LAST_MODIFIED_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
540
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
541 ngx_http_time(pos, r->headers_out.last_modified_time);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
542 len = sizeof("Wed, 31 Dec 1986 18:00:00 GMT") - 1;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
543
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
544 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
545 "http2 output header: \"last-modified: %*s\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
546 len, pos);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
547
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
548 /*
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
549 * Date will always be encoded using huffman in the temporary buffer,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
550 * so it's safe here to use src and dst pointing to the same address.
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
551 */
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
552 pos = ngx_http_v2_write_value(pos, pos, len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
553 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
554
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
555 if (r->headers_out.location && r->headers_out.location->value.len) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
556 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
557 "http2 output header: \"location: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
558 &r->headers_out.location->value);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
559
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
560 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LOCATION_INDEX);
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
561 pos = ngx_http_v2_write_value(pos, r->headers_out.location->value.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
562 r->headers_out.location->value.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
563 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
564
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
565 #if (NGX_HTTP_GZIP)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
566 if (r->gzip_vary) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
567 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
568 "http2 output header: \"vary: Accept-Encoding\"");
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
569
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
570 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_VARY_INDEX);
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
571 pos = ngx_cpymem(pos, accept_encoding, sizeof(accept_encoding));
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
572 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
573 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
574
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
575 part = &r->headers_out.headers.part;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
576 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
577
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
578 for (i = 0; /* void */; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
579
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
580 if (i >= part->nelts) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
581 if (part->next == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
582 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
583 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
584
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
585 part = part->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
586 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
587 i = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
588 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
589
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
590 if (header[i].hash == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
591 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
592 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
593
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
594 #if (NGX_DEBUG)
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
595 if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) {
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
596 ngx_strlow(tmp, header[i].key.data, header[i].key.len);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
597
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
598 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
599 "http2 output header: \"%*s: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
600 header[i].key.len, tmp, &header[i].value);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
601 }
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
602 #endif
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
603
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
604 *pos++ = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
605
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
606 pos = ngx_http_v2_write_name(pos, header[i].key.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
607 header[i].key.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
608
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
609 pos = ngx_http_v2_write_value(pos, header[i].value.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
610 header[i].value.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
611 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
612
7235
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
613 fin = r->header_only
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
614 || (r->headers_out.content_length_n == 0 && !r->expect_trailers);
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
615
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
616 frame = ngx_http_v2_create_headers_frame(r, start, pos, fin);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
617 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
618 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
619 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
620
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
621 ngx_http_v2_queue_blocked_frame(h2c, frame);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
622
9121
262c01782566 HTTP/2: removed server push (ticket #2432).
Sergey Kandaurov <pluknet@nginx.com>
parents: 8024
diff changeset
623 stream->queued = 1;
7004
b624fbf7bee2 HTTP/2: fixed segfault when memory allocation failed.
Valentin Bartenev <vbart@nginx.com>
parents: 6953
diff changeset
624
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
625 cln = ngx_http_cleanup_add(r, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
626 if (cln == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
627 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
628 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
629
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
630 cln->handler = ngx_http_v2_filter_cleanup;
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
631 cln->data = stream;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
632
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
633 fc->send_chain = ngx_http_v2_send_chain;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
634 fc->need_last_buf = 1;
8006
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
635 fc->need_flush_buf = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
636
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
637 return ngx_http_v2_filter_send(fc, stream);
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
638 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
639
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
640
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
641 static ngx_http_v2_out_frame_t *
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
642 ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
643 u_char *end, ngx_uint_t fin)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
644 {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
645 u_char type, flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
646 size_t rest, frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
647 ngx_buf_t *b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
648 ngx_chain_t *cl, **ll;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
649 ngx_http_v2_stream_t *stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
650 ngx_http_v2_out_frame_t *frame;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
651
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
652 stream = r->stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
653 rest = end - pos;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
654
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
655 frame = ngx_palloc(r->pool, sizeof(ngx_http_v2_out_frame_t));
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
656 if (frame == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
657 return NULL;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
658 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
659
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
660 frame->handler = ngx_http_v2_headers_frame_handler;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
661 frame->stream = stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
662 frame->length = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
663 frame->blocked = 1;
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
664 frame->fin = fin;
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
665
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
666 ll = &frame->first;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
667
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
668 type = NGX_HTTP_V2_HEADERS_FRAME;
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
669 flags = fin ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG;
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
670 frame_size = stream->connection->frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
671
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
672 for ( ;; ) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
673 if (rest <= frame_size) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
674 frame_size = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
675 flags |= NGX_HTTP_V2_END_HEADERS_FLAG;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
676 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
677
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
678 b = ngx_create_temp_buf(r->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
679 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
680 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
681 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
682
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
683 b->last = ngx_http_v2_write_len_and_type(b->last, frame_size, type);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
684 *b->last++ = flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
685 b->last = ngx_http_v2_write_sid(b->last, stream->node->id);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
686
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
687 b->tag = (ngx_buf_tag_t) &ngx_http_v2_module;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
688
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
689 cl = ngx_alloc_chain_link(r->pool);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
690 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
691 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
692 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
693
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
694 cl->buf = b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
695
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
696 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
697 ll = &cl->next;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
698
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
699 b = ngx_calloc_buf(r->pool);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
700 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
701 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
702 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
703
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
704 b->pos = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
705
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
706 pos += frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
707
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
708 b->last = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
709 b->start = b->pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
710 b->end = b->last;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
711 b->temporary = 1;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
712
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
713 cl = ngx_alloc_chain_link(r->pool);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
714 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
715 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
716 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
717
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
718 cl->buf = b;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
719
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
720 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
721 ll = &cl->next;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
722
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
723 rest -= frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
724
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
725 if (rest) {
6952
afc60bd9008f HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6885
diff changeset
726 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
afc60bd9008f HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6885
diff changeset
727
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
728 type = NGX_HTTP_V2_CONTINUATION_FRAME;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
729 flags = NGX_HTTP_V2_NO_FLAG;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
730 continue;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
731 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
732
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
733 b->last_buf = fin;
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
734 cl->next = NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
735 frame->last = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
736
7241
190591ab0d76 HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7235
diff changeset
737 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
190591ab0d76 HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7235
diff changeset
738 "http2:%ui create HEADERS frame %p: len:%uz fin:%ui",
190591ab0d76 HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7235
diff changeset
739 stream->node->id, frame, frame->length, fin);
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
740
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
741 return frame;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
742 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
743 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
744
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
745
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
746 static ngx_http_v2_out_frame_t *
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
747 ngx_http_v2_create_trailers_frame(ngx_http_request_t *r)
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
748 {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
749 u_char *pos, *start, *tmp;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
750 size_t len, tmp_len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
751 ngx_uint_t i;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
752 ngx_list_part_t *part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
753 ngx_table_elt_t *header;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
754 ngx_connection_t *fc;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
755
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
756 fc = r->connection;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
757 len = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
758 tmp_len = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
759
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
760 part = &r->headers_out.trailers.part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
761 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
762
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
763 for (i = 0; /* void */; i++) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
764
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
765 if (i >= part->nelts) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
766 if (part->next == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
767 break;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
768 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
769
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
770 part = part->next;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
771 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
772 i = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
773 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
774
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
775 if (header[i].hash == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
776 continue;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
777 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
778
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
779 if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
780 ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
781 "too long response trailer name: \"%V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
782 &header[i].key);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
783 return NULL;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
784 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
785
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
786 if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
787 ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
788 "too long response trailer value: \"%V: %V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
789 &header[i].key, &header[i].value);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
790 return NULL;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
791 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
792
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
793 len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
794 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
795
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
796 if (header[i].key.len > tmp_len) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
797 tmp_len = header[i].key.len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
798 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
799
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
800 if (header[i].value.len > tmp_len) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
801 tmp_len = header[i].value.len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
802 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
803 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
804
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
805 if (len == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
806 return NGX_HTTP_V2_NO_TRAILERS;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
807 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
808
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
809 tmp = ngx_palloc(r->pool, tmp_len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
810 pos = ngx_pnalloc(r->pool, len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
811
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
812 if (pos == NULL || tmp == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
813 return NULL;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
814 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
815
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
816 start = pos;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
817
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
818 part = &r->headers_out.trailers.part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
819 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
820
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
821 for (i = 0; /* void */; i++) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
822
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
823 if (i >= part->nelts) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
824 if (part->next == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
825 break;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
826 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
827
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
828 part = part->next;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
829 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
830 i = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
831 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
832
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
833 if (header[i].hash == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
834 continue;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
835 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
836
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
837 #if (NGX_DEBUG)
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
838 if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
839 ngx_strlow(tmp, header[i].key.data, header[i].key.len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
840
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
841 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0,
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
842 "http2 output trailer: \"%*s: %V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
843 header[i].key.len, tmp, &header[i].value);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
844 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
845 #endif
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
846
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
847 *pos++ = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
848
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
849 pos = ngx_http_v2_write_name(pos, header[i].key.data,
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
850 header[i].key.len, tmp);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
851
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
852 pos = ngx_http_v2_write_value(pos, header[i].value.data,
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
853 header[i].value.len, tmp);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
854 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
855
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
856 return ngx_http_v2_create_headers_frame(r, start, pos, 1);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
857 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
858
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
859
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
860 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
861 ngx_http_v2_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
862 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
863 off_t size, offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
864 size_t rest, frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
865 ngx_chain_t *cl, *out, **ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
866 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
867 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
868 ngx_http_v2_loc_conf_t *h2lcf;
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
869 ngx_http_v2_out_frame_t *frame, *trailers;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
870 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
871
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
872 r = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
873 stream = r->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
874
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
875 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
876 size = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
877 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
878
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
879 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
880 "http2 send chain: %p", in);
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
881
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
882 while (in) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
883 size = ngx_buf_size(in->buf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
884
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
885 if (size || in->buf->last_buf) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
886 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
887 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
888
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
889 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
890 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
891
7235
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
892 if (in == NULL || stream->out_closed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
893
7537
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
894 if (size) {
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
895 ngx_log_error(NGX_LOG_ERR, fc->log, 0,
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
896 "output on closed stream");
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
897 return NGX_CHAIN_ERROR;
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
898 }
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
899
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
900 if (ngx_http_v2_filter_send(fc, stream) == NGX_ERROR) {
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
901 return NGX_CHAIN_ERROR;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
902 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
903
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
904 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
905 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
906
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
907 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
908
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
909 if (size && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) {
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
910
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
911 if (ngx_http_v2_filter_send(fc, stream) == NGX_ERROR) {
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
912 return NGX_CHAIN_ERROR;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
913 }
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
914
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
915 if (ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) {
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
916 fc->write->active = 1;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
917 fc->write->ready = 0;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
918 return in;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
919 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
920 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
921
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
922 if (in->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
923 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
924 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
925 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
926 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
927
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
928 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
929 in->buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
930
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
931 offset = ngx_buf_in_memory(in->buf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
932 ? (cl->buf->pos - in->buf->pos)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
933 : (cl->buf->file_pos - in->buf->file_pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
934
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
935 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
936 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
937
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
938 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
939 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
940 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
941
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
942 if (limit == 0 || limit > (off_t) h2c->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
943 limit = h2c->send_window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
944 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
945
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
946 if (limit > stream->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
947 limit = (stream->send_window > 0) ? stream->send_window : 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
948 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
949
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
950 h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
951
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
952 frame_size = (h2lcf->chunk_size < h2c->frame_size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
953 ? h2lcf->chunk_size : h2c->frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
954
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
955 trailers = NGX_HTTP_V2_NO_TRAILERS;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
956
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
957 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
958 cl = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
959 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
960
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
961 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
962 if ((off_t) frame_size > limit) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
963 frame_size = (size_t) limit;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
964 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
965
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
966 ln = &out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
967 rest = frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
968
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
969 while ((off_t) rest >= size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
970
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
971 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
972 cl = ngx_http_v2_filter_get_shadow(stream, in->buf,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
973 offset, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
974 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
975 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
976 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
977
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
978 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
979
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
980 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
981 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
982 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
983 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
984 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
985
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
986 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
987 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
988
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
989 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
990 ln = &cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
991
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
992 rest -= (size_t) size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
993 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
994
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
995 if (in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
996 frame_size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
997 rest = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
998 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
999 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1000
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1001 size = ngx_buf_size(in->buf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1002 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1003
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1004 if (rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1005 cl = ngx_http_v2_filter_get_shadow(stream, in->buf, offset, rest);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1006 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1007 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1008 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1009
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1010 cl->buf->flush = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1011 cl->buf->last_buf = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1012
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1013 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1014
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1015 offset += rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1016 size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1017 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1018
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1019 if (cl->buf->last_buf) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1020 trailers = ngx_http_v2_create_trailers_frame(r);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1021 if (trailers == NULL) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1022 return NGX_CHAIN_ERROR;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1023 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1024
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1025 if (trailers != NGX_HTTP_V2_NO_TRAILERS) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1026 cl->buf->last_buf = 0;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1027 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1028 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1029
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1030 if (frame_size || cl->buf->last_buf) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1031 frame = ngx_http_v2_filter_get_data_frame(stream, frame_size,
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1032 out, cl);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1033 if (frame == NULL) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1034 return NGX_CHAIN_ERROR;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1035 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1036
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1037 ngx_http_v2_queue_frame(h2c, frame);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1038
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1039 h2c->send_window -= frame_size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1040
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1041 stream->send_window -= frame_size;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1042 stream->queued++;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1043 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1044
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1045 if (in == NULL) {
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1046
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1047 if (trailers != NGX_HTTP_V2_NO_TRAILERS) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1048 ngx_http_v2_queue_frame(h2c, trailers);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1049 stream->queued++;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1050 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1051
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1052 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1053 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1054
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1055 limit -= frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1056
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1057 if (limit == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1058 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1059 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1060 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1061
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1062 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1063 cl = ngx_http_v2_filter_get_shadow(stream, in->buf, offset, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1064 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1065 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1066 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1067
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1068 in->buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1069 ngx_free_chain(r->pool, cl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1070 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1071
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1072 if (ngx_http_v2_filter_send(fc, stream) == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1073 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1074 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1075
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1076 if (in && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1077 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1078 fc->write->ready = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1079 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1080
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1081 return in;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1082 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1083
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1084
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1085 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1086 ngx_http_v2_filter_get_shadow(ngx_http_v2_stream_t *stream, ngx_buf_t *buf,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1087 off_t offset, off_t size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1088 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1089 ngx_buf_t *chunk;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1090 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1091
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1092 cl = ngx_chain_get_free_buf(stream->request->pool, &stream->free_bufs);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1093 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1094 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1095 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1096
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1097 chunk = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1098
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1099 ngx_memcpy(chunk, buf, sizeof(ngx_buf_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1100
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1101 chunk->tag = (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1102 chunk->shadow = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1103
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1104 if (ngx_buf_in_memory(chunk)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1105 chunk->pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1106 chunk->last = chunk->pos + size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1107 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1108
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1109 if (chunk->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1110 chunk->file_pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1111 chunk->file_last = chunk->file_pos + size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1112 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1113
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1114 return cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1115 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1116
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1117
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1118 static ngx_http_v2_out_frame_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1119 ngx_http_v2_filter_get_data_frame(ngx_http_v2_stream_t *stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1120 size_t len, ngx_chain_t *first, ngx_chain_t *last)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1121 {
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1122 u_char flags;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1123 ngx_buf_t *buf;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1124 ngx_chain_t *cl;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1125 ngx_http_v2_out_frame_t *frame;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1126 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1127
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1128 frame = stream->free_frames;
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1129 h2c = stream->connection;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1130
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1131 if (frame) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1132 stream->free_frames = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1133
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1134 } else if (h2c->frames < 10000) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1135 frame = ngx_palloc(stream->request->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1136 sizeof(ngx_http_v2_out_frame_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1137 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1138 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1139 }
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1140
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1141 stream->frames++;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1142 h2c->frames++;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1143
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1144 } else {
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1145 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1146 "http2 flood detected");
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1147
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1148 h2c->connection->error = 1;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1149 return NULL;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1150 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1151
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1152 flags = last->buf->last_buf ? NGX_HTTP_V2_END_STREAM_FLAG : 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1153
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1154 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, stream->request->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1155 "http2:%ui create DATA frame %p: len:%uz flags:%ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1156 stream->node->id, frame, len, (ngx_uint_t) flags);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1157
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1158 cl = ngx_chain_get_free_buf(stream->request->pool,
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1159 &stream->free_frame_headers);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1160 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1161 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1162 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1163
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1164 buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1165
6600
6f69e3c0f780 HTTP/2: style.
Piotr Sikora <piotrsikora@google.com>
parents: 6593
diff changeset
1166 if (buf->start == NULL) {
6251
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1167 buf->start = ngx_palloc(stream->request->pool,
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1168 NGX_HTTP_V2_FRAME_HEADER_SIZE);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1169 if (buf->start == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1170 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1171 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1172
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1173 buf->end = buf->start + NGX_HTTP_V2_FRAME_HEADER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1174 buf->last = buf->end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1175
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1176 buf->tag = (ngx_buf_tag_t) &ngx_http_v2_module;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1177 buf->memory = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1178 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1179
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1180 buf->pos = buf->start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1181 buf->last = buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1182
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1183 buf->last = ngx_http_v2_write_len_and_type(buf->last, len,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1184 NGX_HTTP_V2_DATA_FRAME);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1185 *buf->last++ = flags;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1186
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1187 buf->last = ngx_http_v2_write_sid(buf->last, stream->node->id);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1188
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1189 cl->next = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1190 first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1191
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1192 last->buf->flush = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1193
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1194 frame->first = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1195 frame->last = last;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1196 frame->handler = ngx_http_v2_data_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1197 frame->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1198 frame->length = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1199 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1200 frame->fin = last->buf->last_buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1201
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1202 return frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1203 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1204
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1205
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1206 static ngx_inline ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1207 ngx_http_v2_flow_control(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1208 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1209 {
6792
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1210 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
7108
2bf605c6edf7 HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
1211 "http2:%ui windows: conn:%uz stream:%z",
6792
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1212 stream->node->id, h2c->send_window, stream->send_window);
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1213
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1214 if (stream->send_window <= 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1215 stream->exhausted = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1216 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1217 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1218
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1219 if (h2c->send_window == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1220 ngx_http_v2_waiting_queue(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1221 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1222 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1223
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1224 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1225 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1226
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1227
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1228 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1229 ngx_http_v2_waiting_queue(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1230 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1231 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1232 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1233 ngx_http_v2_stream_t *s;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1234
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1235 if (stream->waiting) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1236 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1237 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1238
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1239 stream->waiting = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1240
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1241 for (q = ngx_queue_last(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1242 q != ngx_queue_sentinel(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1243 q = ngx_queue_prev(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1244 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1245 s = ngx_queue_data(q, ngx_http_v2_stream_t, queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1247 if (s->node->rank < stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1248 || (s->node->rank == stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1249 && s->node->rel_weight >= stream->node->rel_weight))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1250 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1251 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1252 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1253 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1254
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1255 ngx_queue_insert_after(q, &stream->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1256 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1257
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1258
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1259 static ngx_inline ngx_int_t
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1260 ngx_http_v2_filter_send(ngx_connection_t *fc, ngx_http_v2_stream_t *stream)
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1261 {
8006
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1262 ngx_connection_t *c;
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1263
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1264 c = stream->connection->connection;
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1265
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1266 if (stream->queued == 0 && !c->buffered) {
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1267 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1268 return NGX_OK;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1269 }
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1270
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1271 stream->blocked = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1272
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1273 if (ngx_http_v2_send_output_queue(stream->connection) == NGX_ERROR) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1274 fc->error = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1275 return NGX_ERROR;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1276 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1277
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1278 stream->blocked = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1279
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1280 if (stream->queued) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1281 fc->buffered |= NGX_HTTP_V2_BUFFERED;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1282 fc->write->active = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1283 fc->write->ready = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1284 return NGX_AGAIN;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1285 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1286
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1287 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1288
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1289 return NGX_OK;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1290 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1291
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1292
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1293 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1294 ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1295 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1296 {
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1297 ngx_chain_t *cl, *ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1298 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1299
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1300 stream = frame->stream;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1301 cl = frame->first;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1302
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1303 for ( ;; ) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1304 if (cl->buf->pos != cl->buf->last) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1305 frame->first = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1306
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1307 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1308 "http2:%ui HEADERS frame %p was sent partially",
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1309 stream->node->id, frame);
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1310
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1311 return NGX_AGAIN;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1312 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1313
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1314 ln = cl->next;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1315
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1316 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) {
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1317 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1318 stream->free_frame_headers = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1319
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1320 } else {
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1321 cl->next = stream->free_bufs;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1322 stream->free_bufs = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1323 }
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1324
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1325 if (cl == frame->last) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1326 break;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1327 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1328
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1329 cl = ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1330 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1331
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1332 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1333 "http2:%ui HEADERS frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1334 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1335
6953
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1336 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1337 + frame->length;
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1338
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1339 h2c->payload_bytes += frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1340
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1341 ngx_http_v2_handle_frame(stream, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1342
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1343 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1344
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1345 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1346 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1347
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1348
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1349 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1350 ngx_http_v2_data_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1351 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1352 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1353 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1354 ngx_chain_t *cl, *ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1355 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1356
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1357 stream = frame->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1358 cl = frame->first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1359
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1360 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1361
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1362 if (cl->buf->pos != cl->buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1363 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1364 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1365 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1366
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1367 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1368 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1369
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1370 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1371
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1372 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1373 stream->free_frame_headers = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1374
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1375 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1376 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1377 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1378
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1379 cl = ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1380 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1381
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1382 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1383 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1384 buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1385
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1386 if (ngx_buf_in_memory(buf)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1387 buf->pos = cl->buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1388 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1389
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1390 if (buf->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1391 buf->file_pos = cl->buf->file_pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1392 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1393 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1394
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1395 if (ngx_buf_size(cl->buf) != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1396
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1397 if (cl != frame->first) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1398 frame->first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1399 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1400 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1401
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1402 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1403 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1404 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1405
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1406 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1407 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1408
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1409 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1410
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1411 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1412 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1413 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1414
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1415 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1416 ngx_free_chain(stream->request->pool, cl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1417 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1418
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1419 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1420 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1421 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1422
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1423 cl = ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1424 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1425
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1426 done:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1427
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1428 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1429 "http2:%ui DATA frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1430 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1431
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1432 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1433
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1434 h2c->payload_bytes += frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1435
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1436 ngx_http_v2_handle_frame(stream, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1437
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1438 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1439
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1440 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1441 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1442
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1443
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1444 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1445 ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1446 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1447 {
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1448 ngx_http_request_t *r;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1449 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1450
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1451 r = stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1452
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1453 r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1454
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1455 h2c = stream->connection;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1456
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1457 h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1458
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1459 if (frame->fin) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1460 stream->out_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1461 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1462
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1463 frame->next = stream->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1464 stream->free_frames = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1465
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1466 stream->queued--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1467 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1468
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1469
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1470 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1471 ngx_http_v2_handle_stream(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1472 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1473 {
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1474 ngx_event_t *wev;
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
1475 ngx_connection_t *fc;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1476
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1477 if (stream->waiting || stream->blocked) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1478 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1479 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1480
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
1481 fc = stream->request->connection;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1482
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1483 if (!fc->error && stream->exhausted) {
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
1484 return;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1485 }
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
1486
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1487 wev = fc->write;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1488
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1489 wev->active = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1490 wev->ready = 1;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1491
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1492 if (!fc->error && wev->delayed) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1493 return;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1494 }
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1495
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1496 ngx_post_event(wev, &ngx_posted_events);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1497 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1498
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1499
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1500 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1501 ngx_http_v2_filter_cleanup(void *data)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1502 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1503 ngx_http_v2_stream_t *stream = data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1504
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1505 size_t window;
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1506 ngx_event_t *wev;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1507 ngx_queue_t *q;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1508 ngx_http_v2_out_frame_t *frame, **fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1509 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1510
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1511 if (stream->waiting) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1512 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1513 ngx_queue_remove(&stream->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1514 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1515
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1516 if (stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1517 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1518 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1519
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1520 window = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1521 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1522 fn = &h2c->last_out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1523
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1524 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1525 frame = *fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1526
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1527 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1528 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1529 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1530
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1531 if (frame->stream == stream && !frame->blocked) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1532 *fn = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1533
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1534 window += frame->length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1535
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1536 if (--stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1537 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1538 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1539
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1540 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1541 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1542
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1543 fn = &frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1544 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1545
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1546 if (h2c->send_window == 0 && window) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1547
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1548 while (!ngx_queue_empty(&h2c->waiting)) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1549 q = ngx_queue_head(&h2c->waiting);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1550
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1551 ngx_queue_remove(q);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1552
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1553 stream = ngx_queue_data(q, ngx_http_v2_stream_t, queue);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1554
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1555 stream->waiting = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1556
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1557 wev = stream->request->connection->write;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1558
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1559 wev->active = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1560 wev->ready = 1;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1561
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1562 if (!wev->delayed) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1563 ngx_post_event(wev, &ngx_posted_events);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1564 }
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1565 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1566 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1567
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1568 h2c->send_window += window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1569 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1570
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1571
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1572 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1573 ngx_http_v2_filter_init(ngx_conf_t *cf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1574 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1575 ngx_http_next_header_filter = ngx_http_top_header_filter;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1576 ngx_http_top_header_filter = ngx_http_v2_header_filter;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1577
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1578 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1579 }