Mercurial > hg > nginx-quic
annotate src/http/v2/ngx_http_v2_filter_module.c @ 6412:4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Previously, there were only three timeouts used globally for the whole HTTP/2
connection:
1. Idle timeout for inactivity when there are no streams in processing
(the "http2_idle_timeout" directive);
2. Receive timeout for incomplete frames when there are no streams in
processing (the "http2_recv_timeout" directive);
3. Send timeout when there are frames waiting in the output queue
(the "send_timeout" directive on a server level).
Reaching one of these timeouts leads to HTTP/2 connection close.
This left a number of scenarios when a connection can get stuck without any
processing and timeouts:
1. A client has sent the headers block partially so nginx starts processing
a new stream but cannot continue without the rest of HEADERS and/or
CONTINUATION frames;
2. When nginx waits for the request body;
3. All streams are stuck on exhausted connection or stream windows.
The first idea that was rejected was to detect when the whole connection
gets stuck because of these situations and set the global receive timeout.
The disadvantage of such approach would be inconsistent behaviour in some
typical use cases. For example, if a user never replies to the browser's
question about where to save the downloaded file, the stream will be
eventually closed by a timeout. On the other hand, this will not happen
if there's some activity in other concurrent streams.
Now almost all the request timeouts work like in HTTP/1.x connections, so
the "client_header_timeout", "client_body_timeout", and "send_timeout" are
respected. These timeouts close the request.
The global timeouts work as before.
Previously, the c->write->delayed flag was abused to avoid setting timeouts on
stream events. Now, the "active" and "ready" flags are manipulated instead to
control the processing of individual streams.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Wed, 24 Feb 2016 15:58:07 +0300 |
parents | 6812ca9a8002 |
children | cf3e75cfa951 |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
5 */ |
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 #include <ngx_config.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
10 #include <ngx_http.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
11 #include <nginx.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
12 #include <ngx_http_v2_module.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
13 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
14 |
6279
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
15 /* |
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
16 * 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
|
17 * 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
|
18 */ |
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 #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
|
21 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
22 #define ngx_http_v2_literal_size(h) \ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
23 (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
|
24 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
25 #define ngx_http_v2_indexed(i) (128 + (i)) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
26 #define ngx_http_v2_inc_indexed(i) (64 + (i)) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
27 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
28 #define ngx_http_v2_write_name(dst, src, len, tmp) \ |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
29 ngx_http_v2_string_encode(dst, src, len, tmp, 1) |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
30 #define ngx_http_v2_write_value(dst, src, len, tmp) \ |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
31 ngx_http_v2_string_encode(dst, src, len, tmp, 0) |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
32 |
6276
0efc16d55adb
HTTP/2: introduced NGX_HTTP_V2_ENCODE_* macros.
Valentin Bartenev <vbart@nginx.com>
parents:
6275
diff
changeset
|
33 #define NGX_HTTP_V2_ENCODE_RAW 0 |
0efc16d55adb
HTTP/2: introduced NGX_HTTP_V2_ENCODE_* macros.
Valentin Bartenev <vbart@nginx.com>
parents:
6275
diff
changeset
|
34 #define NGX_HTTP_V2_ENCODE_HUFF 0x80 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
35 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
36 #define NGX_HTTP_V2_STATUS_INDEX 8 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
37 #define NGX_HTTP_V2_STATUS_200_INDEX 8 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
38 #define NGX_HTTP_V2_STATUS_204_INDEX 9 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
39 #define NGX_HTTP_V2_STATUS_206_INDEX 10 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
40 #define NGX_HTTP_V2_STATUS_304_INDEX 11 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
41 #define NGX_HTTP_V2_STATUS_400_INDEX 12 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
42 #define NGX_HTTP_V2_STATUS_404_INDEX 13 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
43 #define NGX_HTTP_V2_STATUS_500_INDEX 14 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
44 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
45 #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX 28 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
46 #define NGX_HTTP_V2_CONTENT_TYPE_INDEX 31 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
47 #define NGX_HTTP_V2_DATE_INDEX 33 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
48 #define NGX_HTTP_V2_LAST_MODIFIED_INDEX 44 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
49 #define NGX_HTTP_V2_LOCATION_INDEX 46 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
50 #define NGX_HTTP_V2_SERVER_INDEX 54 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
51 #define NGX_HTTP_V2_VARY_INDEX 59 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
52 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
53 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
54 static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
55 u_char *tmp, ngx_uint_t lower); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
56 static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
57 ngx_uint_t value); |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
58 static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame( |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
59 ngx_http_request_t *r, u_char *pos, u_char *end); |
6246
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 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
|
62 ngx_chain_t *in, off_t limit); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
63 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
64 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
|
65 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
|
66 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
|
67 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
|
68 ngx_chain_t *last); |
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 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
|
71 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
|
72 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
|
73 ngx_http_v2_stream_t *stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
74 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
75 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
|
76 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
|
77 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
78 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
|
79 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
|
80 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
|
81 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
|
82 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
|
83 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
|
84 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
|
85 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
|
86 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
87 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
|
88 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
89 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
|
90 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
91 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
92 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
|
93 NULL, /* preconfiguration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
94 ngx_http_v2_filter_init, /* postconfiguration */ |
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 NULL, /* create main configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
97 NULL, /* init main configuration */ |
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 NULL, /* create server configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
100 NULL, /* merge server configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
101 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
102 NULL, /* create location configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
103 NULL /* merge location configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
104 }; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
105 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
106 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
107 ngx_module_t ngx_http_v2_filter_module = { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
108 NGX_MODULE_V1, |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
109 &ngx_http_v2_filter_module_ctx, /* module context */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
110 NULL, /* module directives */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
111 NGX_HTTP_MODULE, /* module type */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
112 NULL, /* init master */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
113 NULL, /* init module */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
114 NULL, /* init process */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
115 NULL, /* init thread */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
116 NULL, /* exit thread */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
117 NULL, /* exit process */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
118 NULL, /* exit master */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
119 NGX_MODULE_V1_PADDING |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
120 }; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
121 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
122 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
123 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
|
124 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
125 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
126 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
127 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
|
128 { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
129 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
|
130 size_t len, tmp_len; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
131 ngx_str_t host, location; |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
132 ngx_uint_t i, port; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
133 ngx_list_part_t *part; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
134 ngx_table_elt_t *header; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
135 ngx_connection_t *fc; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
136 ngx_http_cleanup_t *cln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
137 ngx_http_v2_out_frame_t *frame; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
138 ngx_http_core_loc_conf_t *clcf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
139 ngx_http_core_srv_conf_t *cscf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
140 struct sockaddr_in *sin; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
141 #if (NGX_HAVE_INET6) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
142 struct sockaddr_in6 *sin6; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
143 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
144 u_char addr[NGX_SOCKADDR_STRLEN]; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
145 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
146 static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7"; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
147 #if (NGX_HTTP_GZIP) |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
148 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
|
149 "\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
|
150 #endif |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
151 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
152 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
|
153 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
|
154 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
155 if (!r->stream) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
156 return ngx_http_next_header_filter(r); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
157 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
158 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
159 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
|
160 "http2 header filter"); |
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 if (r->header_sent) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
163 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
164 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
165 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
166 r->header_sent = 1; |
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 if (r != r->main) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
169 return NGX_OK; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
172 if (r->method == NGX_HTTP_HEAD) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
173 r->header_only = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
174 } |
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 switch (r->headers_out.status) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
177 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
178 case NGX_HTTP_OK: |
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_200_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_NO_CONTENT: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
183 r->header_only = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
184 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
185 ngx_str_null(&r->headers_out.content_type); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
186 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
187 r->headers_out.content_length = NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
188 r->headers_out.content_length_n = -1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
189 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
190 r->headers_out.last_modified_time = -1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
191 r->headers_out.last_modified = NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
192 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
193 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
|
194 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
195 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
196 case NGX_HTTP_PARTIAL_CONTENT: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
197 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
|
198 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
199 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
200 case NGX_HTTP_NOT_MODIFIED: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
201 r->header_only = 1; |
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_304_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 default: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
206 r->headers_out.last_modified_time = -1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
207 r->headers_out.last_modified = NULL; |
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 switch (r->headers_out.status) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
210 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
211 case NGX_HTTP_BAD_REQUEST: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
212 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
|
213 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
214 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
215 case NGX_HTTP_NOT_FOUND: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
216 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
|
217 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
218 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
219 case NGX_HTTP_INTERNAL_SERVER_ERROR: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
220 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
|
221 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
222 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
223 default: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
224 status = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
225 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
226 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
227 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
228 len = status ? 1 : 1 + ngx_http_v2_literal_size("418"); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
229 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
230 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
|
231 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
232 if (r->headers_out.server == NULL) { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
233 len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx)); |
6246
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
236 if (r->headers_out.date == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
237 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
|
238 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
239 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
240 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
|
241 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
|
242 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
243 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
|
244 && r->headers_out.charset.len) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
245 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
246 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
|
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
250 if (r->headers_out.content_length == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
251 && r->headers_out.content_length_n >= 0) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
252 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
253 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
|
254 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
255 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
256 if (r->headers_out.last_modified == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
257 && r->headers_out.last_modified_time != -1) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
258 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
259 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
|
260 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
261 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
262 fc = r->connection; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
263 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
264 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
|
265 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
266 if (r->headers_out.location->value.data[0] == '/') { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
267 if (clcf->server_name_in_redirect) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
268 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
|
269 host = cscf->server_name; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
270 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
271 } else if (r->headers_in.server.len) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
272 host = r->headers_in.server; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
273 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
274 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
275 host.len = NGX_SOCKADDR_STRLEN; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
276 host.data = addr; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
277 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
278 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
|
279 return NGX_ERROR; |
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 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
282 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
283 switch (fc->local_sockaddr->sa_family) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
284 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
285 #if (NGX_HAVE_INET6) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
286 case AF_INET6: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
287 sin6 = (struct sockaddr_in6 *) fc->local_sockaddr; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
288 port = ntohs(sin6->sin6_port); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
289 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
290 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
291 #if (NGX_HAVE_UNIX_DOMAIN) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
292 case AF_UNIX: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
293 port = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
294 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
295 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
296 default: /* AF_INET */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
297 sin = (struct sockaddr_in *) fc->local_sockaddr; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
298 port = ntohs(sin->sin_port); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
299 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
300 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
301 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
302 location.len = sizeof("https://") - 1 + host.len |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
303 + r->headers_out.location->value.len; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
304 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
305 if (clcf->port_in_redirect) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
306 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
307 #if (NGX_HTTP_SSL) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
308 if (fc->ssl) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
309 port = (port == 443) ? 0 : port; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
310 else |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
311 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
312 port = (port == 80) ? 0 : port; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
313 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
314 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
315 port = 0; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
318 if (port) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
319 location.len += sizeof(":65535") - 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
320 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
321 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
322 location.data = ngx_pnalloc(r->pool, location.len); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
323 if (location.data == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
324 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
325 } |
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 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
|
328 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
329 #if (NGX_HTTP_SSL) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
330 if (fc->ssl) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
331 *p++ = 's'; |
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 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
334 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
335 *p++ = ':'; *p++ = '/'; *p++ = '/'; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
336 p = ngx_cpymem(p, host.data, host.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 if (port) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
339 p = ngx_sprintf(p, ":%ui", port); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
340 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
341 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
342 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
|
343 r->headers_out.location->value.len); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
344 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
345 /* 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
|
346 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
347 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
|
348 r->headers_out.location->value.data = location.data; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
349 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
|
350 } |
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 r->headers_out.location->hash = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
353 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
354 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
|
355 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
356 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
357 tmp_len = len; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
358 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
359 #if (NGX_HTTP_GZIP) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
360 if (r->gzip_vary) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
361 if (clcf->gzip_vary) { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
362 len += 1 + sizeof(accept_encoding); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
363 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
364 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
365 r->gzip_vary = 0; |
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 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
368 #endif |
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 part = &r->headers_out.headers.part; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
371 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
372 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
373 for (i = 0; /* void */; i++) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
374 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
375 if (i >= part->nelts) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
376 if (part->next == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
377 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
378 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
379 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
380 part = part->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
381 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
382 i = 0; |
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 if (header[i].hash == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
386 continue; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
387 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
388 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
389 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
|
390 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
|
391 "too long response header name: \"%V\"", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
392 &header[i].key); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
393 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
394 } |
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 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
|
397 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
|
398 "too long response header value: \"%V: %V\"", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
399 &header[i].key, &header[i].value); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
400 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
401 } |
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 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
|
404 + 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
|
405 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
406 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
|
407 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
|
408 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
409 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
410 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
|
411 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
|
412 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
413 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
414 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
415 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
|
416 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
|
417 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
418 if (pos == NULL || tmp == NULL) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
419 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
420 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
421 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
422 start = pos; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
423 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
424 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
|
425 "http2 output header: \":status: %03ui\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
426 r->headers_out.status); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
427 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
428 if (status) { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
429 *pos++ = status; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
430 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
431 } else { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
432 *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
|
433 *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
|
434 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
|
435 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
436 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
437 if (r->headers_out.server == NULL) { |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
438 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
|
439 "http2 output header: \"server: %s\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
440 clcf->server_tokens ? NGINX_VER : "nginx"); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
441 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
442 *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
|
443 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
444 if (clcf->server_tokens) { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
445 if (nginx_ver[0] == '\0') { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
446 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
|
447 sizeof(NGINX_VER) - 1, tmp); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
448 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
|
449 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
450 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
451 pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
452 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
453 } else { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
454 pos = ngx_cpymem(pos, nginx, sizeof(nginx)); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
455 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
456 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
457 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
458 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
|
459 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
|
460 "http2 output header: \"date: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
461 &ngx_cached_http_time); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
462 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
463 *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
|
464 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
|
465 ngx_cached_http_time.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
466 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
467 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
468 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
|
469 *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
|
470 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
471 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
|
472 && r->headers_out.charset.len) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
473 { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
474 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
|
475 + r->headers_out.charset.len; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
476 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
477 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
|
478 if (p == NULL) { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
479 return NGX_ERROR; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
480 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
481 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
482 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
|
483 r->headers_out.content_type.len); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
484 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
485 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
|
486 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
487 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
|
488 r->headers_out.charset.len); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
489 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
490 /* 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
|
491 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
492 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
|
493 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
|
494 } |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
495 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
496 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
|
497 "http2 output header: \"content-type: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
498 &r->headers_out.content_type); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
499 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
500 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
|
501 r->headers_out.content_type.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
502 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
503 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
504 if (r->headers_out.content_length == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
505 && r->headers_out.content_length_n >= 0) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
506 { |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
507 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
|
508 "http2 output header: \"content-length: %O\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
509 r->headers_out.content_length_n); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
510 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
511 *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
|
512 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
513 p = pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
514 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
|
515 *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
|
516 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
517 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
518 if (r->headers_out.last_modified == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
519 && r->headers_out.last_modified_time != -1) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
520 { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
521 *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
|
522 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
523 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
|
524 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
|
525 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
526 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
|
527 "http2 output header: \"last-modified: %*s\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
528 len, pos); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
529 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
530 /* |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
531 * 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
|
532 * 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
|
533 */ |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
534 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
|
535 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
536 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
537 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
|
538 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
|
539 "http2 output header: \"location: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
540 &r->headers_out.location->value); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
541 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
542 *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
|
543 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
|
544 r->headers_out.location->value.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
545 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
546 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
547 #if (NGX_HTTP_GZIP) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
548 if (r->gzip_vary) { |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
549 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
|
550 "http2 output header: \"vary: Accept-Encoding\""); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
551 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
552 *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
|
553 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
|
554 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
555 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
556 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
557 part = &r->headers_out.headers.part; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
558 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
559 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
560 for (i = 0; /* void */; i++) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
561 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
562 if (i >= part->nelts) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
563 if (part->next == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
564 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
565 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
566 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
567 part = part->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
568 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
569 i = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
570 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
571 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
572 if (header[i].hash == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
573 continue; |
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 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
576 #if (NGX_DEBUG) |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
577 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
|
578 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
|
579 |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
580 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
|
581 "http2 output header: \"%*s: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
582 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
|
583 } |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
584 #endif |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
585 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
586 *pos++ = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
587 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
588 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
|
589 header[i].key.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
590 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
591 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
|
592 header[i].value.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
593 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
594 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
595 frame = ngx_http_v2_create_headers_frame(r, start, pos); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
596 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
597 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
598 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
599 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
600 ngx_http_v2_queue_blocked_frame(r->stream->connection, frame); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
601 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
602 cln = ngx_http_cleanup_add(r, 0); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
603 if (cln == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
604 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
605 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
606 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
607 cln->handler = ngx_http_v2_filter_cleanup; |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
608 cln->data = r->stream; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
609 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
610 r->stream->queued = 1; |
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 fc->send_chain = ngx_http_v2_send_chain; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
613 fc->need_last_buf = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
614 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
615 return ngx_http_v2_filter_send(fc, r->stream); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
616 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
617 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
618 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
619 static u_char * |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
620 ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp, |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
621 ngx_uint_t lower) |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
622 { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
623 size_t hlen; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
624 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
625 hlen = ngx_http_v2_huff_encode(src, len, tmp, lower); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
626 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
627 if (hlen > 0) { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
628 *dst = NGX_HTTP_V2_ENCODE_HUFF; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
629 dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), hlen); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
630 return ngx_cpymem(dst, tmp, hlen); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
631 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
632 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
633 *dst = NGX_HTTP_V2_ENCODE_RAW; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
634 dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), len); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
635 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
636 if (lower) { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
637 ngx_strlow(dst, src, len); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
638 return dst + len; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
639 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
640 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
641 return ngx_cpymem(dst, src, len); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
642 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
643 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
644 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
645 static u_char * |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
646 ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
647 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
648 if (value < prefix) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
649 *pos++ |= value; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
650 return pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
651 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
652 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
653 *pos++ |= prefix; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
654 value -= prefix; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
655 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
656 while (value >= 128) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
657 *pos++ = value % 128 + 128; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
658 value /= 128; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
659 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
660 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
661 *pos++ = (u_char) value; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
662 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
663 return pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
664 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
665 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
666 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
667 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
|
668 ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos, |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
669 u_char *end) |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
670 { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
671 u_char type, flags; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
672 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
|
673 ngx_buf_t *b; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
674 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
|
675 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
|
676 ngx_http_v2_out_frame_t *frame; |
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 stream = r->stream; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
679 rest = end - pos; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
680 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
681 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
|
682 if (frame == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
683 return NULL; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
684 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
685 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
686 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
|
687 frame->stream = stream; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
688 frame->length = rest; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
689 frame->blocked = 1; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
690 frame->fin = r->header_only; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
691 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
692 ll = &frame->first; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
693 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
694 type = NGX_HTTP_V2_HEADERS_FRAME; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
695 flags = r->header_only ? NGX_HTTP_V2_END_STREAM_FLAG : 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
|
696 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
|
697 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
698 for ( ;; ) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
699 if (rest <= frame_size) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
700 frame_size = rest; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
701 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
|
702 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
703 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
704 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
|
705 if (b == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
706 return NULL; |
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 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
709 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
|
710 *b->last++ = flags; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
711 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
|
712 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
713 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
|
714 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
715 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
|
716 if (cl == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
717 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
718 } |
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 cl->buf = b; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
721 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
722 *ll = cl; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
723 ll = &cl->next; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
724 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
725 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
|
726 if (b == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
727 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
728 } |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
729 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
730 b->pos = pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
731 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
732 pos += frame_size; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
733 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
734 b->last = pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
735 b->start = b->pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
736 b->end = b->last; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
737 b->temporary = 1; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
738 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
739 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
|
740 if (cl == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
741 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
742 } |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
743 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
744 cl->buf = b; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
745 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
746 *ll = cl; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
747 ll = &cl->next; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
748 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
749 rest -= frame_size; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
750 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
751 if (rest) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
752 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
|
753 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
|
754 continue; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
755 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
756 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
757 b->last_buf = r->header_only; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
758 cl->next = NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
759 frame->last = cl; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
760 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
761 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
762 "http2:%ui create HEADERS frame %p: len:%uz", |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
763 stream->node->id, frame, frame->length); |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
764 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
765 return frame; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
766 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
767 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
768 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
769 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
770 static ngx_chain_t * |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
771 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
|
772 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
773 off_t size, offset; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
774 size_t rest, frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
775 ngx_chain_t *cl, *out, **ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
776 ngx_http_request_t *r; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
777 ngx_http_v2_stream_t *stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
778 ngx_http_v2_loc_conf_t *h2lcf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
779 ngx_http_v2_out_frame_t *frame; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
780 ngx_http_v2_connection_t *h2c; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
781 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
782 r = fc->data; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
783 stream = r->stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
784 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
785 #if (NGX_SUPPRESS_WARN) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
786 size = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
787 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
788 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
789 while (in) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
790 size = ngx_buf_size(in->buf); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
791 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
792 if (size || in->buf->last_buf) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
793 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
794 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
795 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
796 in = in->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
797 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
798 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
799 if (in == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
800 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
801 if (stream->queued) { |
6412
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
802 fc->write->active = 1; |
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
803 fc->write->ready = 0; |
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
804 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
805 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
806 fc->buffered &= ~NGX_HTTP_V2_BUFFERED; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
807 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
808 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
809 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
810 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
811 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
812 h2c = stream->connection; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
813 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
814 if (size && 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
|
815 fc->write->active = 1; |
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
816 fc->write->ready = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
817 return in; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
818 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
819 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
820 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
|
821 cl = ngx_alloc_chain_link(r->pool); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
822 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
823 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
824 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
825 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
826 cl->buf = in->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
827 in->buf = cl->buf->shadow; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
828 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
829 offset = ngx_buf_in_memory(in->buf) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
830 ? (cl->buf->pos - in->buf->pos) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
831 : (cl->buf->file_pos - in->buf->file_pos); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
832 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
833 cl->next = stream->free_bufs; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
834 stream->free_bufs = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
835 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
836 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
837 offset = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
838 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
839 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
840 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
|
841 limit = h2c->send_window; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
842 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
843 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
844 if (limit > stream->send_window) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
845 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
|
846 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
847 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
848 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
|
849 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
850 frame_size = (h2lcf->chunk_size < h2c->frame_size) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
851 ? h2lcf->chunk_size : h2c->frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
852 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
853 #if (NGX_SUPPRESS_WARN) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
854 cl = NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
855 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
856 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
857 for ( ;; ) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
858 if ((off_t) frame_size > limit) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
859 frame_size = (size_t) limit; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
860 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
861 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
862 ln = &out; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
863 rest = frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
864 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
865 while ((off_t) rest >= size) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
866 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
867 if (offset) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
868 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
|
869 offset, size); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
870 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
871 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
872 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
873 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
874 offset = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
875 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
876 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
877 cl = ngx_alloc_chain_link(r->pool); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
878 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
879 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
880 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
881 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
882 cl->buf = in->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
883 } |
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 *ln = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
886 ln = &cl->next; |
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 rest -= (size_t) size; |
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 if (in == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
892 frame_size -= rest; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
893 rest = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
894 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
895 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
896 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
897 size = ngx_buf_size(in->buf); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
898 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
899 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
900 if (rest) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
901 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
|
902 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
903 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
904 } |
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 cl->buf->flush = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
907 cl->buf->last_buf = 0; |
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 *ln = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
910 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
911 offset += rest; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
912 size -= rest; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
913 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
914 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
915 frame = ngx_http_v2_filter_get_data_frame(stream, frame_size, out, cl); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
916 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
917 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
918 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
919 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
920 ngx_http_v2_queue_frame(h2c, frame); |
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 h2c->send_window -= frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
923 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
924 stream->send_window -= frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
925 stream->queued++; |
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 if (in == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
928 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
929 } |
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 limit -= frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
932 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
933 if (limit == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
934 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
935 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
936 } |
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 if (offset) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
939 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
|
940 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
941 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
942 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
943 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
944 in->buf = cl->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
945 ngx_free_chain(r->pool, cl); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
946 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
947 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
948 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
|
949 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
950 } |
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 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
|
953 fc->write->active = 1; |
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
954 fc->write->ready = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
955 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
956 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
957 return in; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
958 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
959 |
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 static ngx_chain_t * |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
962 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
|
963 off_t offset, off_t size) |
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 ngx_buf_t *chunk; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
966 ngx_chain_t *cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
967 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
968 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
|
969 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
970 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
971 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
972 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
973 chunk = cl->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
974 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
975 ngx_memcpy(chunk, buf, sizeof(ngx_buf_t)); |
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 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
|
978 chunk->shadow = buf; |
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 if (ngx_buf_in_memory(chunk)) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
981 chunk->pos += offset; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
982 chunk->last = chunk->pos + size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
983 } |
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 if (chunk->in_file) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
986 chunk->file_pos += offset; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
987 chunk->file_last = chunk->file_pos + size; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
990 return cl; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
993 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
994 static ngx_http_v2_out_frame_t * |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
995 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
|
996 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
|
997 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
998 u_char flags; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
999 ngx_buf_t *buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1000 ngx_chain_t *cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1001 ngx_http_v2_out_frame_t *frame; |
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 frame = stream->free_frames; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1005 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1006 if (frame) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1007 stream->free_frames = frame->next; |
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 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1010 frame = ngx_palloc(stream->request->pool, |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1011 sizeof(ngx_http_v2_out_frame_t)); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1012 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1013 return NULL; |
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 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1016 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1017 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
|
1018 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1019 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
|
1020 "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
|
1021 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
|
1022 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1023 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
|
1024 &stream->free_frame_headers); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1025 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1026 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1027 } |
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 buf = cl->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1030 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1031 if (!buf->start) { |
6251 | 1032 buf->start = ngx_palloc(stream->request->pool, |
1033 NGX_HTTP_V2_FRAME_HEADER_SIZE); | |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1034 if (buf->start == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1035 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1036 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1037 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1038 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
|
1039 buf->last = buf->end; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1040 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1041 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
|
1042 buf->memory = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1043 } |
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 buf->pos = buf->start; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1046 buf->last = buf->pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1047 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1048 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
|
1049 NGX_HTTP_V2_DATA_FRAME); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1050 *buf->last++ = flags; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1051 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1052 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
|
1053 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1054 cl->next = first; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1055 first = cl; |
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 last->buf->flush = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1058 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1059 frame->first = first; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1060 frame->last = last; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1061 frame->handler = ngx_http_v2_data_frame_handler; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1062 frame->stream = stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1063 frame->length = len; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1064 frame->blocked = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1065 frame->fin = last->buf->last_buf; |
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 return frame; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1068 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1069 |
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 static ngx_inline ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1072 ngx_http_v2_filter_send(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
|
1073 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1074 stream->blocked = 1; |
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 (ngx_http_v2_send_output_queue(stream->connection) == NGX_ERROR) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1077 fc->error = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1078 return NGX_ERROR; |
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 stream->blocked = 0; |
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 if (stream->queued) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1084 fc->buffered |= NGX_HTTP_V2_BUFFERED; |
6412
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
1085 fc->write->active = 1; |
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
1086 fc->write->ready = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1087 return NGX_AGAIN; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1090 fc->buffered &= ~NGX_HTTP_V2_BUFFERED; |
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 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1093 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1094 |
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 static ngx_inline ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1097 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
|
1098 ngx_http_v2_stream_t *stream) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1099 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1100 if (stream->send_window <= 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1101 stream->exhausted = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1102 return NGX_DECLINED; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1105 if (h2c->send_window == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1106 ngx_http_v2_waiting_queue(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1107 return NGX_DECLINED; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1110 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1111 } |
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 static void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1115 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
|
1116 ngx_http_v2_stream_t *stream) |
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 ngx_queue_t *q; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1119 ngx_http_v2_stream_t *s; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1120 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1121 if (stream->handled) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1122 return; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1123 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1124 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1125 stream->handled = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1126 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1127 for (q = ngx_queue_last(&h2c->waiting); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1128 q != ngx_queue_sentinel(&h2c->waiting); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1129 q = ngx_queue_prev(q)) |
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 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
|
1132 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1133 if (s->node->rank < stream->node->rank |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1134 || (s->node->rank == stream->node->rank |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1135 && s->node->rel_weight >= stream->node->rel_weight)) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1136 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1137 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1138 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1139 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1140 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1141 ngx_queue_insert_after(q, &stream->queue); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1142 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1143 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1144 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1145 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1146 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1147 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
|
1148 ngx_http_v2_out_frame_t *frame) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1149 { |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1150 ngx_chain_t *cl, *ln; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1151 ngx_http_v2_stream_t *stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1152 |
6292
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1153 stream = frame->stream; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1154 cl = frame->first; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1155 |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1156 for ( ;; ) { |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1157 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
|
1158 frame->first = cl; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1159 |
6292
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1160 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
|
1161 "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
|
1162 stream->node->id, frame); |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1163 |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1164 return NGX_AGAIN; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1165 } |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1166 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1167 ln = cl->next; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1168 |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1169 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
|
1170 cl->next = stream->free_frame_headers; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1171 stream->free_frame_headers = cl; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1172 |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1173 } else { |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1174 cl->next = stream->free_bufs; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1175 stream->free_bufs = cl; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1176 } |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1177 |
6292
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1178 if (cl == frame->last) { |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1179 break; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1180 } |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1181 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1182 cl = ln; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1183 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1184 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1185 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
|
1186 "http2:%ui HEADERS frame %p was sent", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1187 stream->node->id, frame); |
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 ngx_http_v2_handle_frame(stream, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1190 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1191 ngx_http_v2_handle_stream(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1192 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1193 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1194 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1195 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1196 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1197 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1198 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
|
1199 ngx_http_v2_out_frame_t *frame) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1200 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1201 ngx_buf_t *buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1202 ngx_chain_t *cl, *ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1203 ngx_http_v2_stream_t *stream; |
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 stream = frame->stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1206 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1207 cl = frame->first; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1208 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1209 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
|
1210 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1211 if (cl->buf->pos != cl->buf->last) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1212 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
|
1213 "http2:%ui DATA frame %p was sent partially", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1214 stream->node->id, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1215 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1216 return NGX_AGAIN; |
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 ln = cl->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1220 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1221 cl->next = stream->free_frame_headers; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1222 stream->free_frame_headers = cl; |
6246
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 if (cl == frame->last) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1225 goto done; |
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 cl = ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1229 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1230 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1231 for ( ;; ) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1232 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
|
1233 buf = cl->buf->shadow; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1234 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1235 if (ngx_buf_in_memory(buf)) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1236 buf->pos = cl->buf->pos; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1239 if (buf->in_file) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1240 buf->file_pos = cl->buf->file_pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1241 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1242 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1243 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1244 if (ngx_buf_size(cl->buf) != 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1245 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1246 if (cl != frame->first) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1247 frame->first = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1248 ngx_http_v2_handle_stream(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1249 } |
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 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
|
1252 "http2:%ui DATA frame %p was sent partially", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1253 stream->node->id, frame); |
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 return NGX_AGAIN; |
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 ln = cl->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1259 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1260 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
|
1261 cl->next = stream->free_bufs; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1262 stream->free_bufs = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1263 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1264 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1265 ngx_free_chain(stream->request->pool, cl); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1266 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1267 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1268 if (cl == frame->last) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1269 goto done; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1270 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1271 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1272 cl = ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1273 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1274 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1275 done: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1276 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1277 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
|
1278 "http2:%ui DATA frame %p was sent", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1279 stream->node->id, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1280 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1281 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
|
1282 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1283 ngx_http_v2_handle_frame(stream, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1284 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1285 ngx_http_v2_handle_stream(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1286 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1287 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1288 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1289 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1290 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1291 static ngx_inline void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1292 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
|
1293 ngx_http_v2_out_frame_t *frame) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1294 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1295 ngx_http_request_t *r; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1296 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1297 r = stream->request; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1298 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1299 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
|
1300 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1301 if (frame->fin) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1302 stream->out_closed = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1303 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1304 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1305 frame->next = stream->free_frames; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1306 stream->free_frames = frame; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1307 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1308 stream->queued--; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1309 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1310 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1311 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1312 static ngx_inline void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1313 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
|
1314 ngx_http_v2_stream_t *stream) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1315 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1316 ngx_event_t *wev; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1317 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1318 if (stream->handled || stream->blocked || stream->exhausted) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1319 return; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1320 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1321 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1322 wev = stream->request->connection->write; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1323 |
6412
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
1324 if (!wev->delayed) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1325 stream->handled = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1326 ngx_queue_insert_tail(&h2c->posted, &stream->queue); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1327 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1328 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1329 |
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 static void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1332 ngx_http_v2_filter_cleanup(void *data) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1333 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1334 ngx_http_v2_stream_t *stream = data; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1335 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1336 size_t window; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1337 ngx_http_v2_out_frame_t *frame, **fn; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1338 ngx_http_v2_connection_t *h2c; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1339 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1340 if (stream->handled) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1341 stream->handled = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1342 ngx_queue_remove(&stream->queue); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1343 } |
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 if (stream->queued == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1346 return; |
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 window = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1350 h2c = stream->connection; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1351 fn = &h2c->last_out; |
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 for ( ;; ) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1354 frame = *fn; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1355 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1356 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1357 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1358 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1359 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1360 if (frame->stream == stream && !frame->blocked) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1361 *fn = frame->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1362 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1363 window += frame->length; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1364 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1365 if (--stream->queued == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1366 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1367 } |
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 continue; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1370 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1371 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1372 fn = &frame->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1373 } |
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 (h2c->send_window == 0 && window && !ngx_queue_empty(&h2c->waiting)) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1376 ngx_queue_add(&h2c->posted, &h2c->waiting); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1377 ngx_queue_init(&h2c->waiting); |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1380 h2c->send_window += window; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1383 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1384 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1385 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
|
1386 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1387 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
|
1388 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
|
1389 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1390 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1391 } |