Mercurial > hg > nginx
annotate src/http/v2/ngx_http_v2_filter_module.c @ 7975:a7a77549265e
HTTP/2: fixed sendfile() aio handling.
With sendfile() in threads ("aio threads; sendfile on;"), client connection
can block on writing, waiting for sendfile() to complete. In HTTP/2 this
might result in the request hang, since an attempt to continue processing
in thread event handler will call request's write event handler, which
is usually stopped by ngx_http_v2_send_chain(): it does nothing if there
are no additional data and stream->queued is set. Further, HTTP/2 resets
stream's c->write->ready to 0 if writing blocks, so just fixing
ngx_http_v2_send_chain() is not enough.
Can be reproduced with test suite on Linux with:
TEST_NGINX_GLOBALS_HTTP="aio threads; sendfile on;" prove h2*.t
The following tests currently fail: h2_keepalive.t, h2_priority.t,
h2_proxy_max_temp_file_size.t, h2.t, h2_trailers.t.
Similarly, sendfile() with AIO preloading on FreeBSD can block as well,
with similar results. This is, however, harder to reproduce, especially
on modern FreeBSD systems, since sendfile() usually does not return EBUSY.
Fix is to modify ngx_http_v2_send_chain() so it actually tries to send
data to the main connection when called, and to make sure that
c->write->ready is set by the relevant event handlers.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 25 Nov 2021 22:02:10 +0300 |
parents | 80359395b345 |
children | 32b0ba4855a6 |
rev | line source |
---|---|
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2 /* |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
3 * Copyright (C) Nginx, Inc. |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
4 * Copyright (C) Valentin V. Bartenev |
7201 | 5 * Copyright (C) Ruslan Ermilov |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
6 */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
7 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
8 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
9 #include <ngx_config.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
10 #include <ngx_core.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
11 #include <ngx_http.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
12 #include <nginx.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
13 #include <ngx_http_v2_module.h> |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
14 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
15 |
6279
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
16 /* |
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
17 * This returns precise number of octets for values in range 0..253 |
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
18 * and estimate number for the rest, but not smaller than required. |
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
19 */ |
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
20 |
c72eaf694d99
HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents:
6277
diff
changeset
|
21 #define ngx_http_v2_integer_octets(v) (1 + (v) / 127) |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
22 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
23 #define ngx_http_v2_literal_size(h) \ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
24 (ngx_http_v2_integer_octets(sizeof(h) - 1) + sizeof(h) - 1) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
25 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
26 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
27 #define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1 |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
28 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
29 |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
30 typedef struct { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
31 ngx_str_t name; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
32 u_char index; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
33 ngx_uint_t offset; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
34 } ngx_http_v2_push_header_t; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
35 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
36 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
37 static ngx_http_v2_push_header_t ngx_http_v2_push_headers[] = { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
38 { ngx_string(":authority"), NGX_HTTP_V2_AUTHORITY_INDEX, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
39 offsetof(ngx_http_headers_in_t, host) }, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
40 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
41 { ngx_string("accept-encoding"), NGX_HTTP_V2_ACCEPT_ENCODING_INDEX, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
42 offsetof(ngx_http_headers_in_t, accept_encoding) }, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
43 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
44 { ngx_string("accept-language"), NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
45 offsetof(ngx_http_headers_in_t, accept_language) }, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
46 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
47 { ngx_string("user-agent"), NGX_HTTP_V2_USER_AGENT_INDEX, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
48 offsetof(ngx_http_headers_in_t, user_agent) }, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
49 }; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
50 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
51 #define NGX_HTTP_V2_PUSH_HEADERS \ |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
52 (sizeof(ngx_http_v2_push_headers) / sizeof(ngx_http_v2_push_header_t)) |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
53 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
54 |
7201 | 55 static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r); |
56 static ngx_int_t ngx_http_v2_push_resource(ngx_http_request_t *r, | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
57 ngx_str_t *path, ngx_str_t *binary); |
7201 | 58 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
59 static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame( |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
60 ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin); |
7201 | 61 static ngx_http_v2_out_frame_t *ngx_http_v2_create_push_frame( |
62 ngx_http_request_t *r, u_char *pos, u_char *end); | |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
63 static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame( |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
64 ngx_http_request_t *r); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
65 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
66 static ngx_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
|
67 ngx_chain_t *in, off_t limit); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
68 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
69 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
|
70 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
|
71 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
|
72 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
|
73 ngx_chain_t *last); |
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_flow_control( |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
76 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
|
77 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
|
78 ngx_http_v2_stream_t *stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
79 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
80 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
|
81 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
|
82 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
83 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
|
84 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); |
7201 | 85 static ngx_int_t ngx_http_v2_push_frame_handler( |
86 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); | |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
87 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
|
88 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
|
89 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
|
90 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
|
91 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
|
92 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
|
93 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
94 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
|
95 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
96 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
|
97 |
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 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
|
100 NULL, /* preconfiguration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
101 ngx_http_v2_filter_init, /* postconfiguration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
102 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
103 NULL, /* create main configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
104 NULL, /* init main configuration */ |
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 NULL, /* create server configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
107 NULL, /* merge server configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
108 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
109 NULL, /* create location configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
110 NULL /* merge location configuration */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
111 }; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
112 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
113 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
114 ngx_module_t ngx_http_v2_filter_module = { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
115 NGX_MODULE_V1, |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
116 &ngx_http_v2_filter_module_ctx, /* module context */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
117 NULL, /* module directives */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
118 NGX_HTTP_MODULE, /* module type */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
119 NULL, /* init master */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
120 NULL, /* init module */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
121 NULL, /* init process */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
122 NULL, /* init thread */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
123 NULL, /* exit thread */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
124 NULL, /* exit process */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
125 NULL, /* exit master */ |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
126 NGX_MODULE_V1_PADDING |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
127 }; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
128 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
129 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
130 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
|
131 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
132 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
133 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
134 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
|
135 { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
136 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
|
137 size_t len, tmp_len; |
6451
155871d773cc
Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6449
diff
changeset
|
138 ngx_str_t host, location; |
7235
c2a0a838c40f
gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7229
diff
changeset
|
139 ngx_uint_t i, port, fin; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
140 ngx_list_part_t *part; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
141 ngx_table_elt_t *header; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
142 ngx_connection_t *fc; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
143 ngx_http_cleanup_t *cln; |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
144 ngx_http_v2_stream_t *stream; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
145 ngx_http_v2_out_frame_t *frame; |
7100
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
146 ngx_http_v2_connection_t *h2c; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
147 ngx_http_core_loc_conf_t *clcf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
148 ngx_http_core_srv_conf_t *cscf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
149 u_char addr[NGX_SOCKADDR_STRLEN]; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
150 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
151 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
|
152 #if (NGX_HTTP_GZIP) |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
153 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
|
154 "\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
|
155 #endif |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
156 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
157 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
|
158 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
|
159 |
6885
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
160 static size_t nginx_ver_build_len = |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
161 ngx_http_v2_literal_size(NGINX_VER_BUILD); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
162 static u_char nginx_ver_build[ngx_http_v2_literal_size(NGINX_VER_BUILD)]; |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
163 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
164 stream = r->stream; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
165 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
166 if (!stream) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
167 return ngx_http_next_header_filter(r); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
168 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
169 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
170 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
|
171 "http2 header filter"); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
172 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
173 if (r->header_sent) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
174 return NGX_OK; |
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
177 r->header_sent = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
178 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
179 if (r != r->main) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
180 return NGX_OK; |
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 |
6637
699e409a3e0c
HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents:
6600
diff
changeset
|
183 fc = r->connection; |
699e409a3e0c
HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents:
6600
diff
changeset
|
184 |
699e409a3e0c
HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents:
6600
diff
changeset
|
185 if (fc->error) { |
699e409a3e0c
HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents:
6600
diff
changeset
|
186 return NGX_ERROR; |
699e409a3e0c
HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents:
6600
diff
changeset
|
187 } |
699e409a3e0c
HTTP/2: prevented output of the HEADERS frame for canceled streams.
Valentin Bartenev <vbart@nginx.com>
parents:
6600
diff
changeset
|
188 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
189 if (r->method == NGX_HTTP_HEAD) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
190 r->header_only = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
191 } |
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 switch (r->headers_out.status) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
194 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
195 case NGX_HTTP_OK: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
196 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
|
197 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
198 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
199 case NGX_HTTP_NO_CONTENT: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
200 r->header_only = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
201 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
202 ngx_str_null(&r->headers_out.content_type); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
203 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
204 r->headers_out.content_length = NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
205 r->headers_out.content_length_n = -1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
206 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
207 r->headers_out.last_modified_time = -1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
208 r->headers_out.last_modified = NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
209 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
210 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
|
211 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
212 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
213 case NGX_HTTP_PARTIAL_CONTENT: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
214 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
|
215 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
216 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
217 case NGX_HTTP_NOT_MODIFIED: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
218 r->header_only = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
219 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
|
220 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
221 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
222 default: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
223 r->headers_out.last_modified_time = -1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
224 r->headers_out.last_modified = NULL; |
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 switch (r->headers_out.status) { |
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 case NGX_HTTP_BAD_REQUEST: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
229 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
|
230 break; |
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 case NGX_HTTP_NOT_FOUND: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
233 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
|
234 break; |
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 case NGX_HTTP_INTERNAL_SERVER_ERROR: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
237 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
|
238 break; |
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 default: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
241 status = 0; |
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 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
244 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
245 h2c = stream->connection; |
7100
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
246 |
7201 | 247 if (!h2c->push_disabled && !h2c->goaway |
248 && stream->node->id % 2 == 1 | |
249 && r->method != NGX_HTTP_HEAD) | |
250 { | |
251 if (ngx_http_v2_push_resources(r) != NGX_OK) { | |
252 return NGX_ERROR; | |
253 } | |
254 } | |
255 | |
7100
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
256 len = h2c->table_update ? 1 : 0; |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
257 |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
258 len += status ? 1 : 1 + ngx_http_v2_literal_size("418"); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
259 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
260 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
|
261 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
262 if (r->headers_out.server == NULL) { |
6885
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
263 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
264 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
265 len += 1 + nginx_ver_len; |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
266 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
267 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
268 len += 1 + nginx_ver_build_len; |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
269 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
270 } else { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
271 len += 1 + sizeof(nginx); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
272 } |
6246
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
275 if (r->headers_out.date == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
276 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
|
277 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
278 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
279 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
|
280 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
|
281 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
282 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
|
283 && r->headers_out.charset.len) |
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 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
|
286 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
287 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
288 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
289 if (r->headers_out.content_length == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
290 && r->headers_out.content_length_n >= 0) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
291 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
292 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
|
293 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
294 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
295 if (r->headers_out.last_modified == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
296 && r->headers_out.last_modified_time != -1) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
297 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
298 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
|
299 } |
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 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
|
302 |
6852
d15172ebb400
Core: relative redirects (closes #1000).
Ruslan Ermilov <ru@nginx.com>
parents:
6833
diff
changeset
|
303 if (r->headers_out.location->value.data[0] == '/' |
d15172ebb400
Core: relative redirects (closes #1000).
Ruslan Ermilov <ru@nginx.com>
parents:
6833
diff
changeset
|
304 && clcf->absolute_redirect) |
d15172ebb400
Core: relative redirects (closes #1000).
Ruslan Ermilov <ru@nginx.com>
parents:
6833
diff
changeset
|
305 { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
306 if (clcf->server_name_in_redirect) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
307 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
|
308 host = cscf->server_name; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
309 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
310 } else if (r->headers_in.server.len) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
311 host = r->headers_in.server; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
312 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
313 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
314 host.len = NGX_SOCKADDR_STRLEN; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
315 host.data = addr; |
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 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
|
318 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
319 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
320 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
321 |
6593
b3b7e33083ac
Introduced ngx_inet_get_port() and ngx_inet_set_port() functions.
Roman Arutyunyan <arut@nginx.com>
parents:
6451
diff
changeset
|
322 port = ngx_inet_get_port(fc->local_sockaddr); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
323 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
324 location.len = sizeof("https://") - 1 + host.len |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
325 + r->headers_out.location->value.len; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
326 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
327 if (clcf->port_in_redirect) { |
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 port = (port == 443) ? 0 : port; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
332 else |
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 port = (port == 80) ? 0 : port; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
335 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
336 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
337 port = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
338 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
339 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
340 if (port) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
341 location.len += sizeof(":65535") - 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
342 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
343 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
344 location.data = ngx_pnalloc(r->pool, location.len); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
345 if (location.data == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
346 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
347 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
348 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
349 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
|
350 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
351 #if (NGX_HTTP_SSL) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
352 if (fc->ssl) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
353 *p++ = 's'; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
354 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
355 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
356 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
357 *p++ = ':'; *p++ = '/'; *p++ = '/'; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
358 p = ngx_cpymem(p, host.data, host.len); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
359 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
360 if (port) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
361 p = ngx_sprintf(p, ":%ui", port); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
362 } |
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 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
|
365 r->headers_out.location->value.len); |
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 /* 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
|
368 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
369 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
|
370 r->headers_out.location->value.data = location.data; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
371 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
|
372 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
373 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
374 r->headers_out.location->hash = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
375 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
376 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
|
377 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
378 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
379 tmp_len = len; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
380 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
381 #if (NGX_HTTP_GZIP) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
382 if (r->gzip_vary) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
383 if (clcf->gzip_vary) { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
384 len += 1 + sizeof(accept_encoding); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
385 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
386 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
387 r->gzip_vary = 0; |
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 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
390 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
391 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
392 part = &r->headers_out.headers.part; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
393 header = part->elts; |
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 for (i = 0; /* void */; i++) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
396 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
397 if (i >= part->nelts) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
398 if (part->next == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
399 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
400 } |
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 part = part->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
403 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
404 i = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
405 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
406 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
407 if (header[i].hash == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
408 continue; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
409 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
410 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
411 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
|
412 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
|
413 "too long response header name: \"%V\"", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
414 &header[i].key); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
415 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
416 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
417 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
418 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
|
419 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
|
420 "too long response header value: \"%V: %V\"", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
421 &header[i].key, &header[i].value); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
422 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
423 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
424 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
425 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
|
426 + 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
|
427 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
428 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
|
429 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
|
430 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
431 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
432 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
|
433 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
|
434 } |
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 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
437 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
|
438 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
|
439 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
440 if (pos == NULL || tmp == NULL) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
441 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
442 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
443 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
444 start = pos; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
445 |
7100
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
446 if (h2c->table_update) { |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
447 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
448 "http2 table size update: 0"); |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
449 *pos++ = (1 << 5) | 0; |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
450 h2c->table_update = 0; |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
451 } |
12cadc4669a7
HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents:
7035
diff
changeset
|
452 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
453 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
|
454 "http2 output header: \":status: %03ui\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
455 r->headers_out.status); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
456 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
457 if (status) { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
458 *pos++ = status; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
459 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
460 } else { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
461 *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
|
462 *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
|
463 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
|
464 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
465 |
6449
e5076b96fd01
Reconsidered server_tokens with an empty value.
Ruslan Ermilov <ru@nginx.com>
parents:
6434
diff
changeset
|
466 if (r->headers_out.server == NULL) { |
6885
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
467 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
468 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
469 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
470 "http2 output header: \"server: %s\"", |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
471 NGINX_VER); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
472 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
473 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
474 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
475 "http2 output header: \"server: %s\"", |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
476 NGINX_VER_BUILD); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
477 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
478 } else { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
479 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
480 "http2 output header: \"server: nginx\""); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
481 } |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
482 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
483 *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
|
484 |
6885
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
485 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
486 if (nginx_ver[0] == '\0') { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
487 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
|
488 sizeof(NGINX_VER) - 1, tmp); |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
489 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
|
490 } |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
491 |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
492 pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len); |
6451
155871d773cc
Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6449
diff
changeset
|
493 |
6885
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
494 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
495 if (nginx_ver_build[0] == '\0') { |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
496 p = ngx_http_v2_write_value(nginx_ver_build, |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
497 (u_char *) NGINX_VER_BUILD, |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
498 sizeof(NGINX_VER_BUILD) - 1, tmp); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
499 nginx_ver_build_len = p - nginx_ver_build; |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
500 } |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
501 |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
502 pos = ngx_cpymem(pos, nginx_ver_build, nginx_ver_build_len); |
25203fc377fb
Implemented the "server_tokens build" option.
Ruslan Ermilov <ru@nginx.com>
parents:
6852
diff
changeset
|
503 |
6451
155871d773cc
Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6449
diff
changeset
|
504 } else { |
155871d773cc
Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6449
diff
changeset
|
505 pos = ngx_cpymem(pos, nginx, sizeof(nginx)); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
506 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
507 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
508 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
509 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
|
510 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
|
511 "http2 output header: \"date: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
512 &ngx_cached_http_time); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
513 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
514 *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
|
515 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
|
516 ngx_cached_http_time.len, tmp); |
6246
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 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
519 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
|
520 *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
|
521 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
522 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
|
523 && r->headers_out.charset.len) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
524 { |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
525 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
|
526 + r->headers_out.charset.len; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
527 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
528 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
|
529 if (p == NULL) { |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
530 return NGX_ERROR; |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
531 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
532 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
533 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
|
534 r->headers_out.content_type.len); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
535 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
536 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
|
537 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
538 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
|
539 r->headers_out.charset.len); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
540 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
541 /* 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
|
542 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
543 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
|
544 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
|
545 } |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
546 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
547 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
|
548 "http2 output header: \"content-type: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
549 &r->headers_out.content_type); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
550 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
551 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
|
552 r->headers_out.content_type.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
553 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
554 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
555 if (r->headers_out.content_length == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
556 && r->headers_out.content_length_n >= 0) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
557 { |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
558 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
|
559 "http2 output header: \"content-length: %O\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
560 r->headers_out.content_length_n); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
561 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
562 *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
|
563 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
564 p = pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
565 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
|
566 *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
|
567 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
568 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
569 if (r->headers_out.last_modified == NULL |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
570 && r->headers_out.last_modified_time != -1) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
571 { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
572 *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
|
573 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
574 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
|
575 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
|
576 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
577 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
|
578 "http2 output header: \"last-modified: %*s\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
579 len, pos); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
580 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
581 /* |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
582 * 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
|
583 * 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
|
584 */ |
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
585 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
|
586 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
587 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
588 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
|
589 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
|
590 "http2 output header: \"location: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
591 &r->headers_out.location->value); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
592 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
593 *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
|
594 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
|
595 r->headers_out.location->value.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
596 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
597 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
598 #if (NGX_HTTP_GZIP) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
599 if (r->gzip_vary) { |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
600 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
|
601 "http2 output header: \"vary: Accept-Encoding\""); |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
602 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
603 *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
|
604 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
|
605 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
606 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
607 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
608 part = &r->headers_out.headers.part; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
609 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
610 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
611 for (i = 0; /* void */; i++) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
612 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
613 if (i >= part->nelts) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
614 if (part->next == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
615 break; |
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 part = part->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
619 header = part->elts; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
620 i = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
621 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
622 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
623 if (header[i].hash == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
624 continue; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
625 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
626 |
6401
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
627 #if (NGX_DEBUG) |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
628 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
|
629 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
|
630 |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
631 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
|
632 "http2 output header: \"%*s: %V\"", |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
633 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
|
634 } |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
635 #endif |
6812ca9a8002
HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6400
diff
changeset
|
636 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
637 *pos++ = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
638 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
639 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
|
640 header[i].key.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
641 |
6395
ba3c2ca21aa5
HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents:
6377
diff
changeset
|
642 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
|
643 header[i].value.len, tmp); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
644 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
645 |
7235
c2a0a838c40f
gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7229
diff
changeset
|
646 fin = r->header_only |
c2a0a838c40f
gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7229
diff
changeset
|
647 || (r->headers_out.content_length_n == 0 && !r->expect_trailers); |
c2a0a838c40f
gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7229
diff
changeset
|
648 |
c2a0a838c40f
gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7229
diff
changeset
|
649 frame = ngx_http_v2_create_headers_frame(r, start, pos, fin); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
650 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
651 return NGX_ERROR; |
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 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
654 ngx_http_v2_queue_blocked_frame(h2c, frame); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
655 |
7201 | 656 stream->queued++; |
7004
b624fbf7bee2
HTTP/2: fixed segfault when memory allocation failed.
Valentin Bartenev <vbart@nginx.com>
parents:
6953
diff
changeset
|
657 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
658 cln = ngx_http_cleanup_add(r, 0); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
659 if (cln == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
660 return NGX_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
661 } |
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 cln->handler = ngx_http_v2_filter_cleanup; |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
664 cln->data = stream; |
6246
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 fc->send_chain = ngx_http_v2_send_chain; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
667 fc->need_last_buf = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
668 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
669 return ngx_http_v2_filter_send(fc, stream); |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
670 } |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
671 |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
672 |
7201 | 673 static ngx_int_t |
674 ngx_http_v2_push_resources(ngx_http_request_t *r) | |
675 { | |
676 u_char *start, *end, *last; | |
677 ngx_int_t rc; | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
678 ngx_str_t path; |
7201 | 679 ngx_uint_t i, push; |
680 ngx_table_elt_t **h; | |
681 ngx_http_v2_loc_conf_t *h2lcf; | |
682 ngx_http_complex_value_t *pushes; | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
683 ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS]; |
7201 | 684 |
7202
a49af443656f
HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents:
7201
diff
changeset
|
685 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
a49af443656f
HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents:
7201
diff
changeset
|
686 "http2 push resources"); |
7201 | 687 |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
688 ngx_memzero(binary, NGX_HTTP_V2_PUSH_HEADERS * sizeof(ngx_str_t)); |
7201 | 689 |
690 h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module); | |
691 | |
692 if (h2lcf->pushes) { | |
693 pushes = h2lcf->pushes->elts; | |
694 | |
695 for (i = 0; i < h2lcf->pushes->nelts; i++) { | |
696 | |
697 if (ngx_http_complex_value(r, &pushes[i], &path) != NGX_OK) { | |
698 return NGX_ERROR; | |
699 } | |
700 | |
701 if (path.len == 0) { | |
702 continue; | |
703 } | |
704 | |
705 if (path.len == 3 && ngx_strncmp(path.data, "off", 3) == 0) { | |
706 continue; | |
707 } | |
708 | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
709 rc = ngx_http_v2_push_resource(r, &path, binary); |
7201 | 710 |
711 if (rc == NGX_ERROR) { | |
712 return NGX_ERROR; | |
713 } | |
714 | |
715 if (rc == NGX_ABORT) { | |
716 return NGX_OK; | |
717 } | |
718 | |
719 /* NGX_OK, NGX_DECLINED */ | |
720 } | |
721 } | |
722 | |
723 if (!h2lcf->push_preload) { | |
724 return NGX_OK; | |
725 } | |
726 | |
727 h = r->headers_out.link.elts; | |
728 | |
729 for (i = 0; i < r->headers_out.link.nelts; i++) { | |
730 | |
7202
a49af443656f
HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents:
7201
diff
changeset
|
731 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
7201 | 732 "http2 parse link: \"%V\"", &h[i]->value); |
733 | |
734 start = h[i]->value.data; | |
735 end = h[i]->value.data + h[i]->value.len; | |
736 | |
737 next_link: | |
738 | |
739 while (start < end && *start == ' ') { start++; } | |
740 | |
741 if (start == end || *start++ != '<') { | |
742 continue; | |
743 } | |
744 | |
745 while (start < end && *start == ' ') { start++; } | |
746 | |
747 for (last = start; last < end && *last != '>'; last++) { | |
748 /* void */ | |
749 } | |
750 | |
751 if (last == start || last == end) { | |
752 continue; | |
753 } | |
754 | |
755 path.len = last - start; | |
756 path.data = start; | |
757 | |
758 start = last + 1; | |
759 | |
760 while (start < end && *start == ' ') { start++; } | |
761 | |
762 if (start == end) { | |
763 continue; | |
764 } | |
765 | |
766 if (*start == ',') { | |
767 start++; | |
768 goto next_link; | |
769 } | |
770 | |
771 if (*start++ != ';') { | |
772 continue; | |
773 } | |
774 | |
775 last = ngx_strlchr(start, end, ','); | |
776 | |
777 if (last == NULL) { | |
778 last = end; | |
779 } | |
780 | |
781 push = 0; | |
782 | |
783 for ( ;; ) { | |
784 | |
785 while (start < last && *start == ' ') { start++; } | |
786 | |
787 if (last - start >= 6 | |
788 && ngx_strncasecmp(start, (u_char *) "nopush", 6) == 0) | |
789 { | |
790 start += 6; | |
791 | |
792 if (start == last || *start == ' ' || *start == ';') { | |
793 push = 0; | |
794 break; | |
795 } | |
796 | |
797 goto next_param; | |
798 } | |
799 | |
800 if (last - start >= 11 | |
801 && ngx_strncasecmp(start, (u_char *) "rel=preload", 11) == 0) | |
802 { | |
803 start += 11; | |
804 | |
805 if (start == last || *start == ' ' || *start == ';') { | |
806 push = 1; | |
807 } | |
808 | |
809 goto next_param; | |
810 } | |
811 | |
812 if (last - start >= 4 | |
813 && ngx_strncasecmp(start, (u_char *) "rel=", 4) == 0) | |
814 { | |
815 start += 4; | |
816 | |
817 while (start < last && *start == ' ') { start++; } | |
818 | |
819 if (start == last || *start++ != '"') { | |
820 goto next_param; | |
821 } | |
822 | |
823 for ( ;; ) { | |
824 | |
825 while (start < last && *start == ' ') { start++; } | |
826 | |
827 if (last - start >= 7 | |
828 && ngx_strncasecmp(start, (u_char *) "preload", 7) == 0) | |
829 { | |
830 start += 7; | |
831 | |
832 if (start < last && (*start == ' ' || *start == '"')) { | |
833 push = 1; | |
834 break; | |
835 } | |
836 } | |
837 | |
838 while (start < last && *start != ' ' && *start != '"') { | |
839 start++; | |
840 } | |
841 | |
842 if (start == last) { | |
843 break; | |
844 } | |
845 | |
846 if (*start == '"') { | |
847 break; | |
848 } | |
849 | |
850 start++; | |
851 } | |
852 } | |
853 | |
854 next_param: | |
855 | |
856 start = ngx_strlchr(start, last, ';'); | |
857 | |
858 if (start == NULL) { | |
859 break; | |
860 } | |
861 | |
862 start++; | |
863 } | |
864 | |
865 if (push) { | |
866 while (path.len && path.data[path.len - 1] == ' ') { | |
867 path.len--; | |
868 } | |
869 } | |
870 | |
871 if (push && path.len | |
872 && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/')) | |
873 { | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
874 rc = ngx_http_v2_push_resource(r, &path, binary); |
7201 | 875 |
876 if (rc == NGX_ERROR) { | |
877 return NGX_ERROR; | |
878 } | |
879 | |
880 if (rc == NGX_ABORT) { | |
881 return NGX_OK; | |
882 } | |
883 | |
884 /* NGX_OK, NGX_DECLINED */ | |
885 } | |
886 | |
887 if (last < end) { | |
888 start = last + 1; | |
889 goto next_link; | |
890 } | |
891 } | |
892 | |
893 return NGX_OK; | |
894 } | |
895 | |
896 | |
897 static ngx_int_t | |
898 ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path, | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
899 ngx_str_t *binary) |
7201 | 900 { |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
901 u_char *start, *pos, *tmp; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
902 size_t len; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
903 ngx_str_t *value; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
904 ngx_uint_t i; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
905 ngx_table_elt_t **h; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
906 ngx_connection_t *fc; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
907 ngx_http_v2_stream_t *stream; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
908 ngx_http_v2_out_frame_t *frame; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
909 ngx_http_v2_connection_t *h2c; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
910 ngx_http_v2_push_header_t *ph; |
7201 | 911 |
912 fc = r->connection; | |
913 | |
914 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, "http2 push resource"); | |
915 | |
916 stream = r->stream; | |
917 h2c = stream->connection; | |
918 | |
919 if (!ngx_path_separator(path->data[0])) { | |
920 ngx_log_error(NGX_LOG_WARN, fc->log, 0, | |
921 "non-absolute path \"%V\" not pushed", path); | |
922 return NGX_DECLINED; | |
923 } | |
924 | |
925 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, | |
7204 | 926 "http2 pushing:%ui limit:%ui", |
927 h2c->pushing, h2c->concurrent_pushes); | |
7201 | 928 |
929 if (h2c->pushing >= h2c->concurrent_pushes) { | |
930 return NGX_ABORT; | |
931 } | |
932 | |
933 if (h2c->last_push == 0x7ffffffe) { | |
934 return NGX_ABORT; | |
935 } | |
936 | |
937 if (path->len > NGX_HTTP_V2_MAX_FIELD) { | |
938 return NGX_DECLINED; | |
939 } | |
940 | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
941 if (r->headers_in.host == NULL) { |
7203
8b0553239592
HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents:
7202
diff
changeset
|
942 return NGX_ABORT; |
8b0553239592
HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents:
7202
diff
changeset
|
943 } |
8b0553239592
HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents:
7202
diff
changeset
|
944 |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
945 ph = ngx_http_v2_push_headers; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
946 |
7296
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
947 len = ngx_max(r->schema.len, path->len); |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
948 |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
949 if (binary[0].len) { |
7296
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
950 tmp = ngx_palloc(r->pool, len); |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
951 if (tmp == NULL) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
952 return NGX_ERROR; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
953 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
954 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
955 } else { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
956 for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
957 h = (ngx_table_elt_t **) ((char *) &r->headers_in + ph[i].offset); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
958 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
959 if (*h) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
960 len = ngx_max(len, (*h)->value.len); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
961 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
962 } |
7201 | 963 |
964 tmp = ngx_palloc(r->pool, len); | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
965 if (tmp == NULL) { |
7201 | 966 return NGX_ERROR; |
967 } | |
968 | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
969 for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
970 h = (ngx_table_elt_t **) ((char *) &r->headers_in + ph[i].offset); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
971 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
972 if (*h == NULL) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
973 continue; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
974 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
975 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
976 value = &(*h)->value; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
977 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
978 len = 1 + NGX_HTTP_V2_INT_OCTETS + value->len; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
979 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
980 pos = ngx_pnalloc(r->pool, len); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
981 if (pos == NULL) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
982 return NGX_ERROR; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
983 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
984 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
985 binary[i].data = pos; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
986 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
987 *pos++ = ngx_http_v2_inc_indexed(ph[i].index); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
988 pos = ngx_http_v2_write_value(pos, value->data, value->len, tmp); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
989 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
990 binary[i].len = pos - binary[i].data; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
991 } |
7201 | 992 } |
993 | |
994 len = (h2c->table_update ? 1 : 0) | |
995 + 1 | |
996 + 1 + NGX_HTTP_V2_INT_OCTETS + path->len | |
7296
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
997 + 1 + NGX_HTTP_V2_INT_OCTETS + r->schema.len; |
7201 | 998 |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
999 for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1000 len += binary[i].len; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1001 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1002 |
7201 | 1003 pos = ngx_pnalloc(r->pool, len); |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1004 if (pos == NULL) { |
7201 | 1005 return NGX_ERROR; |
1006 } | |
1007 | |
1008 start = pos; | |
1009 | |
1010 if (h2c->table_update) { | |
1011 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, | |
1012 "http2 table size update: 0"); | |
1013 *pos++ = (1 << 5) | 0; | |
1014 h2c->table_update = 0; | |
1015 } | |
1016 | |
1017 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, | |
1018 "http2 push header: \":method: GET\""); | |
1019 | |
1020 *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_METHOD_GET_INDEX); | |
1021 | |
1022 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, | |
1023 "http2 push header: \":path: %V\"", path); | |
1024 | |
1025 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_PATH_INDEX); | |
1026 pos = ngx_http_v2_write_value(pos, path->data, path->len, tmp); | |
1027 | |
7296
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1028 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1029 "http2 push header: \":scheme: %V\"", &r->schema); |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1030 |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1031 if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) { |
7201 | 1032 *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTPS_INDEX); |
1033 | |
7296
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1034 } else if (r->schema.len == 4 |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1035 && ngx_strncmp(r->schema.data, "http", 4) == 0) |
7201 | 1036 { |
1037 *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTP_INDEX); | |
7296
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1038 |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1039 } else { |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1040 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SCHEME_HTTP_INDEX); |
8e6bb4e6045f
HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents:
7241
diff
changeset
|
1041 pos = ngx_http_v2_write_value(pos, r->schema.data, r->schema.len, tmp); |
7201 | 1042 } |
1043 | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1044 for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1045 h = (ngx_table_elt_t **) ((char *) &r->headers_in + ph[i].offset); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1046 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1047 if (*h == NULL) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1048 continue; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1049 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1050 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1051 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1052 "http2 push header: \"%V: %V\"", |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1053 &ph[i].name, &(*h)->value); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1054 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1055 pos = ngx_cpymem(pos, binary[i].data, binary[i].len); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1056 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1057 |
7201 | 1058 frame = ngx_http_v2_create_push_frame(r, start, pos); |
1059 if (frame == NULL) { | |
1060 return NGX_ERROR; | |
1061 } | |
1062 | |
1063 ngx_http_v2_queue_blocked_frame(h2c, frame); | |
1064 | |
1065 stream->queued++; | |
1066 | |
7207
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1067 stream = ngx_http_v2_push_stream(stream, path); |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1068 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1069 if (stream) { |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1070 stream->request->request_length = pos - start; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1071 return NGX_OK; |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1072 } |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1073 |
3d2b0b02bd3d
HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents:
7204
diff
changeset
|
1074 return NGX_ERROR; |
7201 | 1075 } |
1076 | |
1077 | |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1078 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
|
1079 ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos, |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1080 u_char *end, ngx_uint_t fin) |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1081 { |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1082 u_char type, flags; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1083 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
|
1084 ngx_buf_t *b; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1085 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
|
1086 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
|
1087 ngx_http_v2_out_frame_t *frame; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1088 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1089 stream = r->stream; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1090 rest = end - pos; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1091 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1092 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
|
1093 if (frame == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1094 return NULL; |
6246
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 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1097 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
|
1098 frame->stream = stream; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1099 frame->length = rest; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1100 frame->blocked = 1; |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1101 frame->fin = fin; |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1102 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1103 ll = &frame->first; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1104 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1105 type = NGX_HTTP_V2_HEADERS_FRAME; |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1106 flags = fin ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG; |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1107 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
|
1108 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1109 for ( ;; ) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1110 if (rest <= frame_size) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1111 frame_size = rest; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1112 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
|
1113 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1114 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1115 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
|
1116 if (b == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1117 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1118 } |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1119 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1120 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
|
1121 *b->last++ = flags; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1122 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
|
1123 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1124 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
|
1125 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1126 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
|
1127 if (cl == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1128 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1129 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1130 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1131 cl->buf = b; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1132 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1133 *ll = cl; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1134 ll = &cl->next; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1135 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1136 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
|
1137 if (b == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1138 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1139 } |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1140 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1141 b->pos = pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1142 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1143 pos += frame_size; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1144 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1145 b->last = pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1146 b->start = b->pos; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1147 b->end = b->last; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1148 b->temporary = 1; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1149 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1150 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
|
1151 if (cl == NULL) { |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1152 return NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1153 } |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1154 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1155 cl->buf = b; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1156 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1157 *ll = cl; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1158 ll = &cl->next; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1159 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1160 rest -= frame_size; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1161 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1162 if (rest) { |
6952
afc60bd9008f
HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents:
6885
diff
changeset
|
1163 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE; |
afc60bd9008f
HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents:
6885
diff
changeset
|
1164 |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1165 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
|
1166 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
|
1167 continue; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1168 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1169 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1170 b->last_buf = fin; |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1171 cl->next = NULL; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1172 frame->last = cl; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1173 |
7241
190591ab0d76
HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7235
diff
changeset
|
1174 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
190591ab0d76
HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7235
diff
changeset
|
1175 "http2:%ui create HEADERS frame %p: len:%uz fin:%ui", |
190591ab0d76
HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7235
diff
changeset
|
1176 stream->node->id, frame, frame->length, fin); |
6277
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1177 |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1178 return frame; |
b930e598a199
HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6276
diff
changeset
|
1179 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1180 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1181 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1182 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1183 static ngx_http_v2_out_frame_t * |
7201 | 1184 ngx_http_v2_create_push_frame(ngx_http_request_t *r, u_char *pos, u_char *end) |
1185 { | |
1186 u_char type, flags; | |
1187 size_t rest, frame_size, len; | |
1188 ngx_buf_t *b; | |
1189 ngx_chain_t *cl, **ll; | |
1190 ngx_http_v2_stream_t *stream; | |
1191 ngx_http_v2_out_frame_t *frame; | |
1192 ngx_http_v2_connection_t *h2c; | |
1193 | |
1194 stream = r->stream; | |
1195 h2c = stream->connection; | |
1196 rest = NGX_HTTP_V2_STREAM_ID_SIZE + (end - pos); | |
1197 | |
1198 frame = ngx_palloc(r->pool, sizeof(ngx_http_v2_out_frame_t)); | |
1199 if (frame == NULL) { | |
1200 return NULL; | |
1201 } | |
1202 | |
1203 frame->handler = ngx_http_v2_push_frame_handler; | |
1204 frame->stream = stream; | |
1205 frame->length = rest; | |
1206 frame->blocked = 1; | |
1207 frame->fin = 0; | |
1208 | |
1209 ll = &frame->first; | |
1210 | |
1211 type = NGX_HTTP_V2_PUSH_PROMISE_FRAME; | |
1212 flags = NGX_HTTP_V2_NO_FLAG; | |
1213 frame_size = h2c->frame_size; | |
1214 | |
1215 for ( ;; ) { | |
1216 if (rest <= frame_size) { | |
1217 frame_size = rest; | |
1218 flags |= NGX_HTTP_V2_END_HEADERS_FLAG; | |
1219 } | |
1220 | |
1221 b = ngx_create_temp_buf(r->pool, | |
1222 NGX_HTTP_V2_FRAME_HEADER_SIZE | |
1223 + ((type == NGX_HTTP_V2_PUSH_PROMISE_FRAME) | |
1224 ? NGX_HTTP_V2_STREAM_ID_SIZE : 0)); | |
1225 if (b == NULL) { | |
1226 return NULL; | |
1227 } | |
1228 | |
1229 b->last = ngx_http_v2_write_len_and_type(b->last, frame_size, type); | |
1230 *b->last++ = flags; | |
1231 b->last = ngx_http_v2_write_sid(b->last, stream->node->id); | |
1232 | |
1233 b->tag = (ngx_buf_tag_t) &ngx_http_v2_module; | |
1234 | |
1235 if (type == NGX_HTTP_V2_PUSH_PROMISE_FRAME) { | |
1236 h2c->last_push += 2; | |
1237 | |
1238 b->last = ngx_http_v2_write_sid(b->last, h2c->last_push); | |
1239 len = frame_size - NGX_HTTP_V2_STREAM_ID_SIZE; | |
1240 | |
1241 } else { | |
1242 len = frame_size; | |
1243 } | |
1244 | |
1245 cl = ngx_alloc_chain_link(r->pool); | |
1246 if (cl == NULL) { | |
1247 return NULL; | |
1248 } | |
1249 | |
1250 cl->buf = b; | |
1251 | |
1252 *ll = cl; | |
1253 ll = &cl->next; | |
1254 | |
1255 b = ngx_calloc_buf(r->pool); | |
1256 if (b == NULL) { | |
1257 return NULL; | |
1258 } | |
1259 | |
1260 b->pos = pos; | |
1261 | |
1262 pos += len; | |
1263 | |
1264 b->last = pos; | |
1265 b->start = b->pos; | |
1266 b->end = b->last; | |
1267 b->temporary = 1; | |
1268 | |
1269 cl = ngx_alloc_chain_link(r->pool); | |
1270 if (cl == NULL) { | |
1271 return NULL; | |
1272 } | |
1273 | |
1274 cl->buf = b; | |
1275 | |
1276 *ll = cl; | |
1277 ll = &cl->next; | |
1278 | |
1279 rest -= frame_size; | |
1280 | |
1281 if (rest) { | |
1282 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE; | |
1283 | |
1284 type = NGX_HTTP_V2_CONTINUATION_FRAME; | |
1285 continue; | |
1286 } | |
1287 | |
1288 cl->next = NULL; | |
1289 frame->last = cl; | |
1290 | |
1291 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1292 "http2:%ui create PUSH_PROMISE frame %p: " | |
1293 "sid:%ui len:%uz", | |
1294 stream->node->id, frame, h2c->last_push, | |
1295 frame->length); | |
1296 | |
1297 return frame; | |
1298 } | |
1299 } | |
1300 | |
1301 | |
1302 static ngx_http_v2_out_frame_t * | |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1303 ngx_http_v2_create_trailers_frame(ngx_http_request_t *r) |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1304 { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1305 u_char *pos, *start, *tmp; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1306 size_t len, tmp_len; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1307 ngx_uint_t i; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1308 ngx_list_part_t *part; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1309 ngx_table_elt_t *header; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1310 ngx_connection_t *fc; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1311 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1312 fc = r->connection; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1313 len = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1314 tmp_len = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1315 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1316 part = &r->headers_out.trailers.part; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1317 header = part->elts; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1318 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1319 for (i = 0; /* void */; i++) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1320 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1321 if (i >= part->nelts) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1322 if (part->next == NULL) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1323 break; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1324 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1325 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1326 part = part->next; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1327 header = part->elts; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1328 i = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1329 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1330 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1331 if (header[i].hash == 0) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1332 continue; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1333 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1334 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1335 if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1336 ngx_log_error(NGX_LOG_CRIT, fc->log, 0, |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1337 "too long response trailer name: \"%V\"", |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1338 &header[i].key); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1339 return NULL; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1340 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1341 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1342 if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1343 ngx_log_error(NGX_LOG_CRIT, fc->log, 0, |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1344 "too long response trailer value: \"%V: %V\"", |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1345 &header[i].key, &header[i].value); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1346 return NULL; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1347 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1348 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1349 len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1350 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1351 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1352 if (header[i].key.len > tmp_len) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1353 tmp_len = header[i].key.len; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1354 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1355 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1356 if (header[i].value.len > tmp_len) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1357 tmp_len = header[i].value.len; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1358 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1359 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1360 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1361 if (len == 0) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1362 return NGX_HTTP_V2_NO_TRAILERS; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1363 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1364 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1365 tmp = ngx_palloc(r->pool, tmp_len); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1366 pos = ngx_pnalloc(r->pool, len); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1367 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1368 if (pos == NULL || tmp == NULL) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1369 return NULL; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1370 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1371 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1372 start = pos; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1373 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1374 part = &r->headers_out.trailers.part; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1375 header = part->elts; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1376 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1377 for (i = 0; /* void */; i++) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1378 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1379 if (i >= part->nelts) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1380 if (part->next == NULL) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1381 break; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1382 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1383 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1384 part = part->next; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1385 header = part->elts; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1386 i = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1387 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1388 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1389 if (header[i].hash == 0) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1390 continue; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1391 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1392 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1393 #if (NGX_DEBUG) |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1394 if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1395 ngx_strlow(tmp, header[i].key.data, header[i].key.len); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1396 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1397 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1398 "http2 output trailer: \"%*s: %V\"", |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1399 header[i].key.len, tmp, &header[i].value); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1400 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1401 #endif |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1402 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1403 *pos++ = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1404 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1405 pos = ngx_http_v2_write_name(pos, header[i].key.data, |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1406 header[i].key.len, tmp); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1407 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1408 pos = ngx_http_v2_write_value(pos, header[i].value.data, |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1409 header[i].value.len, tmp); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1410 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1411 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1412 return ngx_http_v2_create_headers_frame(r, start, pos, 1); |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1413 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1414 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1415 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1416 static ngx_chain_t * |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1417 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
|
1418 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1419 off_t size, offset; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1420 size_t rest, frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1421 ngx_chain_t *cl, *out, **ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1422 ngx_http_request_t *r; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1423 ngx_http_v2_stream_t *stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1424 ngx_http_v2_loc_conf_t *h2lcf; |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1425 ngx_http_v2_out_frame_t *frame, *trailers; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1426 ngx_http_v2_connection_t *h2c; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1427 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1428 r = fc->data; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1429 stream = r->stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1430 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1431 #if (NGX_SUPPRESS_WARN) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1432 size = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1433 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1434 |
7975
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1435 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1436 "http2 send chain: %p", in); |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1437 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1438 while (in) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1439 size = ngx_buf_size(in->buf); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1440 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1441 if (size || in->buf->last_buf) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1442 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1443 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1444 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1445 in = in->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1446 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1447 |
7235
c2a0a838c40f
gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7229
diff
changeset
|
1448 if (in == NULL || stream->out_closed) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1449 |
7537
01e26357916a
HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7296
diff
changeset
|
1450 if (size) { |
01e26357916a
HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7296
diff
changeset
|
1451 ngx_log_error(NGX_LOG_ERR, fc->log, 0, |
01e26357916a
HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7296
diff
changeset
|
1452 "output on closed stream"); |
01e26357916a
HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7296
diff
changeset
|
1453 return NGX_CHAIN_ERROR; |
01e26357916a
HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7296
diff
changeset
|
1454 } |
01e26357916a
HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7296
diff
changeset
|
1455 |
7975
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1456 if (ngx_http_v2_filter_send(fc, stream) == NGX_ERROR) { |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1457 return NGX_CHAIN_ERROR; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1458 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1459 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1460 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1461 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1462 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1463 h2c = stream->connection; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1464 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1465 if (size && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) { |
7975
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1466 |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1467 if (ngx_http_v2_filter_send(fc, stream) == NGX_ERROR) { |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1468 return NGX_CHAIN_ERROR; |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1469 } |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1470 |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1471 if (ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) { |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1472 fc->write->active = 1; |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1473 fc->write->ready = 0; |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1474 return in; |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1475 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1476 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1477 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1478 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
|
1479 cl = ngx_alloc_chain_link(r->pool); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1480 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1481 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1482 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1483 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1484 cl->buf = in->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1485 in->buf = cl->buf->shadow; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1486 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1487 offset = ngx_buf_in_memory(in->buf) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1488 ? (cl->buf->pos - in->buf->pos) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1489 : (cl->buf->file_pos - in->buf->file_pos); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1490 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1491 cl->next = stream->free_bufs; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1492 stream->free_bufs = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1493 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1494 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1495 offset = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1496 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1497 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1498 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
|
1499 limit = h2c->send_window; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1500 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1501 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1502 if (limit > stream->send_window) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1503 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
|
1504 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1505 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1506 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
|
1507 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1508 frame_size = (h2lcf->chunk_size < h2c->frame_size) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1509 ? h2lcf->chunk_size : h2c->frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1510 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1511 trailers = NGX_HTTP_V2_NO_TRAILERS; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1512 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1513 #if (NGX_SUPPRESS_WARN) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1514 cl = NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1515 #endif |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1516 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1517 for ( ;; ) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1518 if ((off_t) frame_size > limit) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1519 frame_size = (size_t) limit; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1520 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1521 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1522 ln = &out; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1523 rest = frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1524 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1525 while ((off_t) rest >= size) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1526 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1527 if (offset) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1528 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
|
1529 offset, size); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1530 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1531 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1532 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1533 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1534 offset = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1535 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1536 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1537 cl = ngx_alloc_chain_link(r->pool); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1538 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1539 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1540 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1541 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1542 cl->buf = in->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1543 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1544 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1545 *ln = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1546 ln = &cl->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1547 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1548 rest -= (size_t) size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1549 in = in->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1550 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1551 if (in == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1552 frame_size -= rest; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1553 rest = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1554 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1555 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1556 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1557 size = ngx_buf_size(in->buf); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1558 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1559 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1560 if (rest) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1561 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
|
1562 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1563 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1564 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1565 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1566 cl->buf->flush = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1567 cl->buf->last_buf = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1568 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1569 *ln = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1570 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1571 offset += rest; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1572 size -= rest; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1573 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1574 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1575 if (cl->buf->last_buf) { |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1576 trailers = ngx_http_v2_create_trailers_frame(r); |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1577 if (trailers == NULL) { |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1578 return NGX_CHAIN_ERROR; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1579 } |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1580 |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1581 if (trailers != NGX_HTTP_V2_NO_TRAILERS) { |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1582 cl->buf->last_buf = 0; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1583 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1584 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1585 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1586 if (frame_size || cl->buf->last_buf) { |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1587 frame = ngx_http_v2_filter_get_data_frame(stream, frame_size, |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1588 out, cl); |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1589 if (frame == NULL) { |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1590 return NGX_CHAIN_ERROR; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1591 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1592 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1593 ngx_http_v2_queue_frame(h2c, frame); |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1594 |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1595 h2c->send_window -= frame_size; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1596 |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1597 stream->send_window -= frame_size; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1598 stream->queued++; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1599 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1600 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1601 if (in == NULL) { |
7035
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1602 |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1603 if (trailers != NGX_HTTP_V2_NO_TRAILERS) { |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1604 ngx_http_v2_queue_frame(h2c, trailers); |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1605 stream->queued++; |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1606 } |
4e784e095a97
HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents:
7004
diff
changeset
|
1607 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1608 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1609 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1610 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1611 limit -= frame_size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1612 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1613 if (limit == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1614 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1615 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1616 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1617 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1618 if (offset) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1619 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
|
1620 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1621 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1622 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1623 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1624 in->buf = cl->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1625 ngx_free_chain(r->pool, cl); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1626 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1627 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1628 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
|
1629 return NGX_CHAIN_ERROR; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1630 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1631 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1632 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
|
1633 fc->write->active = 1; |
4ba91a4c66a3
HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents:
6401
diff
changeset
|
1634 fc->write->ready = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1635 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1636 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1637 return in; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1638 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1639 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1640 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1641 static ngx_chain_t * |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1642 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
|
1643 off_t offset, off_t size) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1644 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1645 ngx_buf_t *chunk; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1646 ngx_chain_t *cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1647 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1648 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
|
1649 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1650 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1651 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1652 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1653 chunk = cl->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1654 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1655 ngx_memcpy(chunk, buf, sizeof(ngx_buf_t)); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1656 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1657 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
|
1658 chunk->shadow = buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1659 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1660 if (ngx_buf_in_memory(chunk)) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1661 chunk->pos += offset; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1662 chunk->last = chunk->pos + size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1663 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1664 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1665 if (chunk->in_file) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1666 chunk->file_pos += offset; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1667 chunk->file_last = chunk->file_pos + size; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1668 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1669 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1670 return cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1671 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1672 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1673 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1674 static ngx_http_v2_out_frame_t * |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1675 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
|
1676 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
|
1677 { |
7548
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1678 u_char flags; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1679 ngx_buf_t *buf; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1680 ngx_chain_t *cl; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1681 ngx_http_v2_out_frame_t *frame; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1682 ngx_http_v2_connection_t *h2c; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1683 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1684 frame = stream->free_frames; |
7548
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1685 h2c = stream->connection; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1686 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1687 if (frame) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1688 stream->free_frames = frame->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1689 |
7548
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1690 } else if (h2c->frames < 10000) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1691 frame = ngx_palloc(stream->request->pool, |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1692 sizeof(ngx_http_v2_out_frame_t)); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1693 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1694 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1695 } |
7548
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1696 |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1697 stream->frames++; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1698 h2c->frames++; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1699 |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1700 } else { |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1701 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1702 "http2 flood detected"); |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1703 |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1704 h2c->connection->error = 1; |
99257b06b0bd
HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents:
7537
diff
changeset
|
1705 return NULL; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1706 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1707 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1708 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
|
1709 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1710 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
|
1711 "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
|
1712 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
|
1713 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1714 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
|
1715 &stream->free_frame_headers); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1716 if (cl == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1717 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1718 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1719 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1720 buf = cl->buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1721 |
6600 | 1722 if (buf->start == NULL) { |
6251 | 1723 buf->start = ngx_palloc(stream->request->pool, |
1724 NGX_HTTP_V2_FRAME_HEADER_SIZE); | |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1725 if (buf->start == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1726 return NULL; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1727 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1728 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1729 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
|
1730 buf->last = buf->end; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1731 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1732 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
|
1733 buf->memory = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1734 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1735 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1736 buf->pos = buf->start; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1737 buf->last = buf->pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1738 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1739 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
|
1740 NGX_HTTP_V2_DATA_FRAME); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1741 *buf->last++ = flags; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1742 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1743 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
|
1744 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1745 cl->next = first; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1746 first = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1747 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1748 last->buf->flush = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1749 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1750 frame->first = first; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1751 frame->last = last; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1752 frame->handler = ngx_http_v2_data_frame_handler; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1753 frame->stream = stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1754 frame->length = len; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1755 frame->blocked = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1756 frame->fin = last->buf->last_buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1757 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1758 return frame; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1759 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1760 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1761 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1762 static ngx_inline ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1763 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
|
1764 ngx_http_v2_stream_t *stream) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1765 { |
6792
45d553812055
HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6638
diff
changeset
|
1766 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, |
7108
2bf605c6edf7
HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7100
diff
changeset
|
1767 "http2:%ui windows: conn:%uz stream:%z", |
6792
45d553812055
HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6638
diff
changeset
|
1768 stream->node->id, h2c->send_window, stream->send_window); |
45d553812055
HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6638
diff
changeset
|
1769 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1770 if (stream->send_window <= 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1771 stream->exhausted = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1772 return NGX_DECLINED; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1773 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1774 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1775 if (h2c->send_window == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1776 ngx_http_v2_waiting_queue(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1777 return NGX_DECLINED; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1778 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1779 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1780 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1781 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1782 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1783 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1784 static void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1785 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
|
1786 ngx_http_v2_stream_t *stream) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1787 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1788 ngx_queue_t *q; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1789 ngx_http_v2_stream_t *s; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1790 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
1791 if (stream->waiting) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1792 return; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1793 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1794 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
1795 stream->waiting = 1; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1796 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1797 for (q = ngx_queue_last(&h2c->waiting); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1798 q != ngx_queue_sentinel(&h2c->waiting); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1799 q = ngx_queue_prev(q)) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1800 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1801 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
|
1802 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1803 if (s->node->rank < stream->node->rank |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1804 || (s->node->rank == stream->node->rank |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1805 && s->node->rel_weight >= stream->node->rel_weight)) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1806 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1807 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1808 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1809 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1810 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1811 ngx_queue_insert_after(q, &stream->queue); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1812 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1813 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1814 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1815 static ngx_inline ngx_int_t |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1816 ngx_http_v2_filter_send(ngx_connection_t *fc, ngx_http_v2_stream_t *stream) |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1817 { |
7975
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1818 if (stream->queued == 0) { |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1819 fc->buffered &= ~NGX_HTTP_V2_BUFFERED; |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1820 return NGX_OK; |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1821 } |
a7a77549265e
HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7569
diff
changeset
|
1822 |
7191
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1823 stream->blocked = 1; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1824 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1825 if (ngx_http_v2_send_output_queue(stream->connection) == NGX_ERROR) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1826 fc->error = 1; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1827 return NGX_ERROR; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1828 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1829 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1830 stream->blocked = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1831 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1832 if (stream->queued) { |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1833 fc->buffered |= NGX_HTTP_V2_BUFFERED; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1834 fc->write->active = 1; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1835 fc->write->ready = 0; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1836 return NGX_AGAIN; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1837 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1838 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1839 fc->buffered &= ~NGX_HTTP_V2_BUFFERED; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1840 |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1841 return NGX_OK; |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1842 } |
61d276dcd493
HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents:
7108
diff
changeset
|
1843 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1844 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1845 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1846 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
|
1847 ngx_http_v2_out_frame_t *frame) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1848 { |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1849 ngx_chain_t *cl, *ln; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1850 ngx_http_v2_stream_t *stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1851 |
6292
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1852 stream = frame->stream; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1853 cl = frame->first; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1854 |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1855 for ( ;; ) { |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1856 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
|
1857 frame->first = cl; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1858 |
6292
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1859 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
|
1860 "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
|
1861 stream->node->id, frame); |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1862 |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1863 return NGX_AGAIN; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1864 } |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1865 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1866 ln = cl->next; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1867 |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1868 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
|
1869 cl->next = stream->free_frame_headers; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1870 stream->free_frame_headers = cl; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1871 |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1872 } else { |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1873 cl->next = stream->free_bufs; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1874 stream->free_bufs = cl; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1875 } |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1876 |
6292
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1877 if (cl == frame->last) { |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1878 break; |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1879 } |
f72d3129cd35
HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents:
6279
diff
changeset
|
1880 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1881 cl = ln; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1882 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1883 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1884 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
|
1885 "http2:%ui HEADERS frame %p was sent", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1886 stream->node->id, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1887 |
6953
663e6a48bfcb
HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents:
6952
diff
changeset
|
1888 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE |
663e6a48bfcb
HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents:
6952
diff
changeset
|
1889 + frame->length; |
663e6a48bfcb
HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents:
6952
diff
changeset
|
1890 |
7569
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
1891 h2c->payload_bytes += frame->length; |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
1892 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1893 ngx_http_v2_handle_frame(stream, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1894 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1895 ngx_http_v2_handle_stream(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1896 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1897 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1898 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1899 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1900 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1901 static ngx_int_t |
7201 | 1902 ngx_http_v2_push_frame_handler(ngx_http_v2_connection_t *h2c, |
1903 ngx_http_v2_out_frame_t *frame) | |
1904 { | |
1905 ngx_chain_t *cl, *ln; | |
1906 ngx_http_v2_stream_t *stream; | |
1907 | |
1908 stream = frame->stream; | |
1909 cl = frame->first; | |
1910 | |
1911 for ( ;; ) { | |
1912 if (cl->buf->pos != cl->buf->last) { | |
1913 frame->first = cl; | |
1914 | |
1915 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, | |
1916 "http2:%ui PUSH_PROMISE frame %p was sent partially", | |
1917 stream->node->id, frame); | |
1918 | |
1919 return NGX_AGAIN; | |
1920 } | |
1921 | |
1922 ln = cl->next; | |
1923 | |
1924 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) { | |
1925 cl->next = stream->free_frame_headers; | |
1926 stream->free_frame_headers = cl; | |
1927 | |
1928 } else { | |
1929 cl->next = stream->free_bufs; | |
1930 stream->free_bufs = cl; | |
1931 } | |
1932 | |
1933 if (cl == frame->last) { | |
1934 break; | |
1935 } | |
1936 | |
1937 cl = ln; | |
1938 } | |
1939 | |
1940 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, | |
1941 "http2:%ui PUSH_PROMISE frame %p was sent", | |
1942 stream->node->id, frame); | |
1943 | |
1944 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE | |
1945 + frame->length; | |
1946 | |
7569
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
1947 h2c->payload_bytes += frame->length; |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
1948 |
7201 | 1949 ngx_http_v2_handle_frame(stream, frame); |
1950 | |
1951 ngx_http_v2_handle_stream(h2c, stream); | |
1952 | |
1953 return NGX_OK; | |
1954 } | |
1955 | |
1956 | |
1957 static ngx_int_t | |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1958 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
|
1959 ngx_http_v2_out_frame_t *frame) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1960 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1961 ngx_buf_t *buf; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1962 ngx_chain_t *cl, *ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1963 ngx_http_v2_stream_t *stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1964 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1965 stream = frame->stream; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1966 cl = frame->first; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1967 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1968 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
|
1969 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1970 if (cl->buf->pos != cl->buf->last) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1971 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
|
1972 "http2:%ui DATA frame %p was sent partially", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1973 stream->node->id, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1974 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1975 return NGX_AGAIN; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1976 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1977 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1978 ln = cl->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1979 |
6293
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1980 cl->next = stream->free_frame_headers; |
ec6b07be88a5
HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents:
6292
diff
changeset
|
1981 stream->free_frame_headers = cl; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1982 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1983 if (cl == frame->last) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1984 goto done; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1985 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1986 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1987 cl = ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1988 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1989 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1990 for ( ;; ) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1991 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
|
1992 buf = cl->buf->shadow; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1993 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1994 if (ngx_buf_in_memory(buf)) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1995 buf->pos = cl->buf->pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1996 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1997 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1998 if (buf->in_file) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
1999 buf->file_pos = cl->buf->file_pos; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2000 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2001 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2002 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2003 if (ngx_buf_size(cl->buf) != 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2004 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2005 if (cl != frame->first) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2006 frame->first = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2007 ngx_http_v2_handle_stream(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2008 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2009 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2010 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
|
2011 "http2:%ui DATA frame %p was sent partially", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2012 stream->node->id, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2013 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2014 return NGX_AGAIN; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2015 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2016 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2017 ln = cl->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2018 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2019 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
|
2020 cl->next = stream->free_bufs; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2021 stream->free_bufs = cl; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2022 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2023 } else { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2024 ngx_free_chain(stream->request->pool, cl); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2025 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2026 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2027 if (cl == frame->last) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2028 goto done; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2029 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2030 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2031 cl = ln; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2032 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2033 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2034 done: |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2035 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2036 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
|
2037 "http2:%ui DATA frame %p was sent", |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2038 stream->node->id, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2039 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2040 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
|
2041 |
7569
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2042 h2c->payload_bytes += frame->length; |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2043 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2044 ngx_http_v2_handle_frame(stream, frame); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2045 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2046 ngx_http_v2_handle_stream(h2c, stream); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2047 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2048 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2049 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2050 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2051 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2052 static ngx_inline void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2053 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
|
2054 ngx_http_v2_out_frame_t *frame) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2055 { |
7569
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2056 ngx_http_request_t *r; |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2057 ngx_http_v2_connection_t *h2c; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2058 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2059 r = stream->request; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2060 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2061 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
|
2062 |
7569
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2063 h2c = stream->connection; |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2064 |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2065 h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length; |
80359395b345
HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7548
diff
changeset
|
2066 |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2067 if (frame->fin) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2068 stream->out_closed = 1; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2069 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2070 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2071 frame->next = stream->free_frames; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2072 stream->free_frames = frame; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2073 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2074 stream->queued--; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2075 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2076 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2077 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2078 static ngx_inline void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2079 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
|
2080 ngx_http_v2_stream_t *stream) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2081 { |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2082 ngx_event_t *wev; |
6638
a2b310a8b2af
HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents:
6637
diff
changeset
|
2083 ngx_connection_t *fc; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2084 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2085 if (stream->waiting || stream->blocked) { |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2086 return; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2087 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2088 |
6638
a2b310a8b2af
HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents:
6637
diff
changeset
|
2089 fc = stream->request->connection; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2090 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2091 if (!fc->error && stream->exhausted) { |
6638
a2b310a8b2af
HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents:
6637
diff
changeset
|
2092 return; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2093 } |
6638
a2b310a8b2af
HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents:
6637
diff
changeset
|
2094 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2095 wev = fc->write; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2096 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2097 wev->active = 0; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2098 wev->ready = 1; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2099 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2100 if (!fc->error && wev->delayed) { |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2101 return; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2102 } |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2103 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2104 ngx_post_event(wev, &ngx_posted_events); |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2105 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2106 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2107 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2108 static void |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2109 ngx_http_v2_filter_cleanup(void *data) |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2110 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2111 ngx_http_v2_stream_t *stream = data; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2112 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2113 size_t window; |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2114 ngx_event_t *wev; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2115 ngx_queue_t *q; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2116 ngx_http_v2_out_frame_t *frame, **fn; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2117 ngx_http_v2_connection_t *h2c; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2118 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2119 if (stream->waiting) { |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2120 stream->waiting = 0; |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2121 ngx_queue_remove(&stream->queue); |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2122 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2123 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2124 if (stream->queued == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2125 return; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2126 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2127 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2128 window = 0; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2129 h2c = stream->connection; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2130 fn = &h2c->last_out; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2131 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2132 for ( ;; ) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2133 frame = *fn; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2134 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2135 if (frame == NULL) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2136 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2137 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2138 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2139 if (frame->stream == stream && !frame->blocked) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2140 *fn = frame->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2141 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2142 window += frame->length; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2143 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2144 if (--stream->queued == 0) { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2145 break; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2146 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2147 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2148 continue; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2149 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2150 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2151 fn = &frame->next; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2152 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2153 |
6833
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2154 if (h2c->send_window == 0 && window) { |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2155 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2156 while (!ngx_queue_empty(&h2c->waiting)) { |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2157 q = ngx_queue_head(&h2c->waiting); |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2158 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2159 ngx_queue_remove(q); |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2160 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2161 stream = ngx_queue_data(q, ngx_http_v2_stream_t, queue); |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2162 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2163 stream->waiting = 0; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2164 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2165 wev = stream->request->connection->write; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2166 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2167 wev->active = 0; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2168 wev->ready = 1; |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2169 |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2170 if (!wev->delayed) { |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2171 ngx_post_event(wev, &ngx_posted_events); |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2172 } |
3834951e32ab
HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents:
6792
diff
changeset
|
2173 } |
6246
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2174 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2175 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2176 h2c->send_window += window; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2177 } |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2178 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2179 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2180 static ngx_int_t |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2181 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
|
2182 { |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2183 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
|
2184 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
|
2185 |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2186 return NGX_OK; |
257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff
changeset
|
2187 } |