annotate src/http/v2/ngx_http_v2_filter_module.c @ 8006:32b0ba4855a6

HTTP/2: made it possible to flush response headers (ticket #1743). Response headers can be buffered in the SSL buffer. But stream's fake connection buffered flag did not reflect this, so any attempts to flush the buffer without sending additional data were stopped by the write filter. It does not seem to be possible to reflect this in fc->buffered though, as we never known if main connection's c->buffered corresponds to the particular stream or not. As such, fc->buffered might prevent request finalization due to sending data on some other stream. Fix is to implement handling of flush buffers when the c->need_flush_buf flag is set, similarly to the existing last buffer handling. The same flag is now used for UDP sockets in the stream module instead of explicit checking of c->type.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 03 Feb 2022 01:44:38 +0300
parents a7a77549265e
children ef6a3a99a81a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3 * Copyright (C) Nginx, Inc.
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4 * Copyright (C) Valentin V. Bartenev
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
5 * Copyright (C) Ruslan Ermilov
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
6 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
7
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
9 #include <ngx_config.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
10 #include <ngx_core.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
11 #include <ngx_http.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
12 #include <nginx.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
13 #include <ngx_http_v2_module.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
14
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
15
6279
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
16 /*
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
17 * This returns precise number of octets for values in range 0..253
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
18 * and estimate number for the rest, but not smaller than required.
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
19 */
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
20
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
21 #define ngx_http_v2_integer_octets(v) (1 + (v) / 127)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
22
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
23 #define ngx_http_v2_literal_size(h) \
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
24 (ngx_http_v2_integer_octets(sizeof(h) - 1) + sizeof(h) - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
25
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
26
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
27 #define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
28
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
29
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
55 static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
61 static ngx_http_v2_out_frame_t *ngx_http_v2_create_push_frame(
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
85 static ngx_int_t ngx_http_v2_push_frame_handler(
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
247 if (!h2c->push_disabled && !h2c->goaway
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
248 && stream->node->id % 2 == 1
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
249 && r->method != NGX_HTTP_HEAD)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
250 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
251 if (ngx_http_v2_push_resources(r) != NGX_OK) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
252 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
253 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
254 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
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;
8006
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
668 fc->need_flush_buf = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
669
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
670 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
671 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
672
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
673
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
674 static ngx_int_t
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
675 ngx_http_v2_push_resources(ngx_http_request_t *r)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
676 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
677 u_char *start, *end, *last;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
678 ngx_int_t rc;
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
679 ngx_str_t path;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
680 ngx_uint_t i, push;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
681 ngx_table_elt_t **h;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
682 ngx_http_v2_loc_conf_t *h2lcf;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
683 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
684 ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS];
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
685
7202
a49af443656f HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents: 7201
diff changeset
686 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
687 "http2 push resources");
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
688
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
689 ngx_memzero(binary, NGX_HTTP_V2_PUSH_HEADERS * sizeof(ngx_str_t));
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
690
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
691 h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
692
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
693 if (h2lcf->pushes) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
694 pushes = h2lcf->pushes->elts;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
695
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
696 for (i = 0; i < h2lcf->pushes->nelts; i++) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
697
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
698 if (ngx_http_complex_value(r, &pushes[i], &path) != NGX_OK) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
699 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
700 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
701
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
702 if (path.len == 0) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
703 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
704 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
705
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
706 if (path.len == 3 && ngx_strncmp(path.data, "off", 3) == 0) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
707 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
708 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
709
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
710 rc = ngx_http_v2_push_resource(r, &path, binary);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
711
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
712 if (rc == NGX_ERROR) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
713 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
714 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
715
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
716 if (rc == NGX_ABORT) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
717 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
718 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
719
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
720 /* NGX_OK, NGX_DECLINED */
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
721 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
722 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
723
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
724 if (!h2lcf->push_preload) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
725 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
726 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
727
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
728 h = r->headers_out.link.elts;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
729
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
730 for (i = 0; i < r->headers_out.link.nelts; i++) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
731
7202
a49af443656f HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents: 7201
diff changeset
732 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
733 "http2 parse link: \"%V\"", &h[i]->value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
734
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
735 start = h[i]->value.data;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
736 end = h[i]->value.data + h[i]->value.len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
737
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
738 next_link:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
739
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
740 while (start < end && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
741
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
742 if (start == end || *start++ != '<') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
743 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
744 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
745
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
746 while (start < end && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
747
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
748 for (last = start; last < end && *last != '>'; last++) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
749 /* void */
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
750 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
751
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
752 if (last == start || last == end) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
753 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
754 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
755
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
756 path.len = last - start;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
757 path.data = start;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
758
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
759 start = last + 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
760
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
761 while (start < end && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
762
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
763 if (start == end) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
764 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
765 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
766
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
767 if (*start == ',') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
768 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
769 goto next_link;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
770 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
771
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
772 if (*start++ != ';') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
773 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
774 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
775
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
776 last = ngx_strlchr(start, end, ',');
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
777
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
778 if (last == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
779 last = end;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
780 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
781
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
782 push = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
783
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
784 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
785
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
786 while (start < last && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
787
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
788 if (last - start >= 6
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
789 && ngx_strncasecmp(start, (u_char *) "nopush", 6) == 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
790 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
791 start += 6;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
792
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
793 if (start == last || *start == ' ' || *start == ';') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
794 push = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
795 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
796 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
797
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
798 goto next_param;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
799 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
800
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
801 if (last - start >= 11
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
802 && ngx_strncasecmp(start, (u_char *) "rel=preload", 11) == 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
803 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
804 start += 11;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
805
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
806 if (start == last || *start == ' ' || *start == ';') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
807 push = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
808 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
809
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
810 goto next_param;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
811 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
812
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
813 if (last - start >= 4
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
814 && ngx_strncasecmp(start, (u_char *) "rel=", 4) == 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
815 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
816 start += 4;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
817
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
818 while (start < last && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
819
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
820 if (start == last || *start++ != '"') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
821 goto next_param;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
822 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
823
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
824 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
825
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
826 while (start < last && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
827
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
828 if (last - start >= 7
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
829 && ngx_strncasecmp(start, (u_char *) "preload", 7) == 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
830 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
831 start += 7;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
832
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
833 if (start < last && (*start == ' ' || *start == '"')) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
834 push = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
835 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
836 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
837 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
838
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
839 while (start < last && *start != ' ' && *start != '"') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
840 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
841 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
842
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
843 if (start == last) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
844 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
845 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
846
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
847 if (*start == '"') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
848 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
849 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
850
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
851 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
852 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
853 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
854
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
855 next_param:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
856
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
857 start = ngx_strlchr(start, last, ';');
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
858
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
859 if (start == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
860 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
861 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
862
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
863 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
864 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
865
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
866 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
867 while (path.len && path.data[path.len - 1] == ' ') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
868 path.len--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
869 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
870 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
871
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
872 if (push && path.len
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
873 && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/'))
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
874 {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
875 rc = ngx_http_v2_push_resource(r, &path, binary);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
876
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
877 if (rc == NGX_ERROR) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
878 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
879 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
880
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
881 if (rc == NGX_ABORT) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
882 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
883 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
884
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
885 /* NGX_OK, NGX_DECLINED */
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
886 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
887
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
888 if (last < end) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
889 start = last + 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
890 goto next_link;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
891 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
892 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
893
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
894 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
895 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
896
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
897
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
898 static ngx_int_t
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
899 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
900 ngx_str_t *binary)
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
901 {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
902 u_char *start, *pos, *tmp;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
903 size_t len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
904 ngx_str_t *value;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
905 ngx_uint_t i;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
906 ngx_table_elt_t **h;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
907 ngx_connection_t *fc;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
908 ngx_http_v2_stream_t *stream;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
909 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
910 ngx_http_v2_connection_t *h2c;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
911 ngx_http_v2_push_header_t *ph;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
912
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
913 fc = r->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
914
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
915 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, "http2 push resource");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
916
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
917 stream = r->stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
918 h2c = stream->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
919
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
920 if (!ngx_path_separator(path->data[0])) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
921 ngx_log_error(NGX_LOG_WARN, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
922 "non-absolute path \"%V\" not pushed", path);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
923 return NGX_DECLINED;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
924 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
925
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
926 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
7204
e44c297a6b95 HTTP/2: style.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7203
diff changeset
927 "http2 pushing:%ui limit:%ui",
e44c297a6b95 HTTP/2: style.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7203
diff changeset
928 h2c->pushing, h2c->concurrent_pushes);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
929
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
930 if (h2c->pushing >= h2c->concurrent_pushes) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
931 return NGX_ABORT;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
932 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
933
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
934 if (h2c->last_push == 0x7ffffffe) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
935 return NGX_ABORT;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
936 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
937
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
938 if (path->len > NGX_HTTP_V2_MAX_FIELD) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
939 return NGX_DECLINED;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
940 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
941
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
942 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
943 return NGX_ABORT;
8b0553239592 HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7202
diff changeset
944 }
8b0553239592 HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7202
diff changeset
945
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
946 ph = ngx_http_v2_push_headers;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
947
7296
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
948 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
949
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
950 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
951 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
952 if (tmp == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
953 return NGX_ERROR;
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
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
956 } else {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
957 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
958 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
959
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
960 if (*h) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
961 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
962 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
963 }
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
964
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
965 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
966 if (tmp == NULL) {
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
967 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
968 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
969
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
970 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
971 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
972
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
973 if (*h == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
974 continue;
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
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
977 value = &(*h)->value;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
978
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
979 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
980
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
981 pos = ngx_pnalloc(r->pool, len);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
982 if (pos == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
983 return NGX_ERROR;
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
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
986 binary[i].data = pos;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
987
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
988 *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
989 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
990
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
991 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
992 }
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
993 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
994
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
995 len = (h2c->table_update ? 1 : 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
996 + 1
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
997 + 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
998 + 1 + NGX_HTTP_V2_INT_OCTETS + r->schema.len;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
999
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1000 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
1001 len += binary[i].len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1002 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1003
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1004 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
1005 if (pos == NULL) {
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1006 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1007 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1008
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1009 start = pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1010
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1011 if (h2c->table_update) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1012 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1013 "http2 table size update: 0");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1014 *pos++ = (1 << 5) | 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1015 h2c->table_update = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1016 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1017
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1018 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1019 "http2 push header: \":method: GET\"");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1020
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1021 *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_METHOD_GET_INDEX);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1022
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1023 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1024 "http2 push header: \":path: %V\"", path);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1025
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1026 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_PATH_INDEX);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1027 pos = ngx_http_v2_write_value(pos, path->data, path->len, tmp);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1028
7296
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
1029 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
1030 "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
1031
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
1032 if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) {
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1033 *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTPS_INDEX);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1034
7296
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
1035 } 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
1036 && ngx_strncmp(r->schema.data, "http", 4) == 0)
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1037 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1038 *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
1039
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
1040 } else {
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_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
1042 pos = ngx_http_v2_write_value(pos, r->schema.data, r->schema.len, tmp);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1043 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1044
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1045 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
1046 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
1047
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1048 if (*h == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1049 continue;
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
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1052 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
1053 "http2 push header: \"%V: %V\"",
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1054 &ph[i].name, &(*h)->value);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1055
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1056 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
1057 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1058
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1059 frame = ngx_http_v2_create_push_frame(r, start, pos);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1060 if (frame == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1061 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1062 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1063
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1064 ngx_http_v2_queue_blocked_frame(h2c, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1065
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1066 stream->queued++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1067
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1068 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
1069
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1070 if (stream) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1071 stream->request->request_length = pos - start;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1072 return NGX_OK;
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
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1075 return NGX_ERROR;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1076 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1077
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1078
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1079 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
1080 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
1081 u_char *end, ngx_uint_t fin)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1082 {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1083 u_char type, flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1084 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
1085 ngx_buf_t *b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1086 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
1087 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
1088 ngx_http_v2_out_frame_t *frame;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1089
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1090 stream = r->stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1091 rest = end - pos;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1092
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1093 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
1094 if (frame == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1095 return NULL;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1096 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1097
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1098 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
1099 frame->stream = stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1100 frame->length = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1101 frame->blocked = 1;
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1102 frame->fin = fin;
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1103
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1104 ll = &frame->first;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1105
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1106 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
1107 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
1108 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
1109
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1110 for ( ;; ) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1111 if (rest <= frame_size) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1112 frame_size = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1113 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
1114 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1115
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1116 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
1117 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1118 return NULL;
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
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1121 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
1122 *b->last++ = flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1123 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
1124
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1125 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
1126
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1127 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
1128 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1129 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1130 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1131
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1132 cl->buf = b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1133
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1134 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1135 ll = &cl->next;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1136
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1137 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
1138 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1139 return NULL;
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
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1142 b->pos = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1143
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1144 pos += frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1145
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1146 b->last = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1147 b->start = b->pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1148 b->end = b->last;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1149 b->temporary = 1;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1150
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1151 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
1152 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1153 return NULL;
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
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1156 cl->buf = b;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1157
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1158 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1159 ll = &cl->next;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1160
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1161 rest -= frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1162
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1163 if (rest) {
6952
afc60bd9008f HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6885
diff changeset
1164 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
afc60bd9008f HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6885
diff changeset
1165
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1166 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
1167 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
1168 continue;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1169 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1170
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1171 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
1172 cl->next = NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1173 frame->last = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1174
7241
190591ab0d76 HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7235
diff changeset
1175 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
1176 "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
1177 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
1178
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1179 return frame;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1180 }
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1183
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1184 static ngx_http_v2_out_frame_t *
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1185 ngx_http_v2_create_push_frame(ngx_http_request_t *r, u_char *pos, u_char *end)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1186 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1187 u_char type, flags;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1188 size_t rest, frame_size, len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1189 ngx_buf_t *b;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1190 ngx_chain_t *cl, **ll;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1191 ngx_http_v2_stream_t *stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1192 ngx_http_v2_out_frame_t *frame;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1193 ngx_http_v2_connection_t *h2c;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1194
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1195 stream = r->stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1196 h2c = stream->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1197 rest = NGX_HTTP_V2_STREAM_ID_SIZE + (end - pos);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1198
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1199 frame = ngx_palloc(r->pool, sizeof(ngx_http_v2_out_frame_t));
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1200 if (frame == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1201 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1202 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1203
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1204 frame->handler = ngx_http_v2_push_frame_handler;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1205 frame->stream = stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1206 frame->length = rest;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1207 frame->blocked = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1208 frame->fin = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1209
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1210 ll = &frame->first;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1211
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1212 type = NGX_HTTP_V2_PUSH_PROMISE_FRAME;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1213 flags = NGX_HTTP_V2_NO_FLAG;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1214 frame_size = h2c->frame_size;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1215
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1216 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1217 if (rest <= frame_size) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1218 frame_size = rest;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1219 flags |= NGX_HTTP_V2_END_HEADERS_FLAG;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1220 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1221
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1222 b = ngx_create_temp_buf(r->pool,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1223 NGX_HTTP_V2_FRAME_HEADER_SIZE
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1224 + ((type == NGX_HTTP_V2_PUSH_PROMISE_FRAME)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1225 ? NGX_HTTP_V2_STREAM_ID_SIZE : 0));
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1226 if (b == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1227 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1228 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1229
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1230 b->last = ngx_http_v2_write_len_and_type(b->last, frame_size, type);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1231 *b->last++ = flags;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1232 b->last = ngx_http_v2_write_sid(b->last, stream->node->id);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1233
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1234 b->tag = (ngx_buf_tag_t) &ngx_http_v2_module;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1235
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1236 if (type == NGX_HTTP_V2_PUSH_PROMISE_FRAME) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1237 h2c->last_push += 2;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1238
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1239 b->last = ngx_http_v2_write_sid(b->last, h2c->last_push);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1240 len = frame_size - NGX_HTTP_V2_STREAM_ID_SIZE;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1241
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1242 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1243 len = frame_size;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1244 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1245
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1246 cl = ngx_alloc_chain_link(r->pool);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1247 if (cl == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1248 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1249 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1250
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1251 cl->buf = b;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1252
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1253 *ll = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1254 ll = &cl->next;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1255
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1256 b = ngx_calloc_buf(r->pool);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1257 if (b == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1258 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1259 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1260
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1261 b->pos = pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1262
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1263 pos += len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1264
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1265 b->last = pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1266 b->start = b->pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1267 b->end = b->last;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1268 b->temporary = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1269
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1270 cl = ngx_alloc_chain_link(r->pool);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1271 if (cl == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1272 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1273 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1274
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1275 cl->buf = b;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1276
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1277 *ll = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1278 ll = &cl->next;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1279
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1280 rest -= frame_size;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1281
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1282 if (rest) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1283 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1284
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1285 type = NGX_HTTP_V2_CONTINUATION_FRAME;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1286 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1287 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1288
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1289 cl->next = NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1290 frame->last = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1291
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1292 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1293 "http2:%ui create PUSH_PROMISE frame %p: "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1294 "sid:%ui len:%uz",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1295 stream->node->id, frame, h2c->last_push,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1296 frame->length);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1297
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1298 return frame;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1299 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1300 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1301
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1302
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1303 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
1304 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
1305 {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1306 u_char *pos, *start, *tmp;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1307 size_t len, tmp_len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1308 ngx_uint_t i;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1309 ngx_list_part_t *part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1310 ngx_table_elt_t *header;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1311 ngx_connection_t *fc;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1312
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1313 fc = r->connection;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1314 len = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1315 tmp_len = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1316
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1317 part = &r->headers_out.trailers.part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1318 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1319
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1320 for (i = 0; /* void */; i++) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1321
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1322 if (i >= part->nelts) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1323 if (part->next == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1324 break;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1327 part = part->next;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1328 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1329 i = 0;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1332 if (header[i].hash == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1333 continue;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1336 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
1337 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
1338 "too long response trailer name: \"%V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1339 &header[i].key);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1340 return NULL;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1343 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
1344 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
1345 "too long response trailer value: \"%V: %V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1346 &header[i].key, &header[i].value);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1347 return NULL;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1350 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
1351 + 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
1352
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1353 if (header[i].key.len > tmp_len) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1354 tmp_len = header[i].key.len;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1357 if (header[i].value.len > tmp_len) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1358 tmp_len = header[i].value.len;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1362 if (len == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1363 return NGX_HTTP_V2_NO_TRAILERS;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1366 tmp = ngx_palloc(r->pool, tmp_len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1367 pos = ngx_pnalloc(r->pool, len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1368
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1369 if (pos == NULL || tmp == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1370 return NULL;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1373 start = pos;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1374
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1375 part = &r->headers_out.trailers.part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1376 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1377
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1378 for (i = 0; /* void */; i++) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1379
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1380 if (i >= part->nelts) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1381 if (part->next == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1382 break;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1385 part = part->next;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1386 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1387 i = 0;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1390 if (header[i].hash == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1391 continue;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1394 #if (NGX_DEBUG)
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1395 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
1396 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
1397
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1398 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
1399 "http2 output trailer: \"%*s: %V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1400 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
1401 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1402 #endif
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1403
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1404 *pos++ = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1405
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1406 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
1407 header[i].key.len, tmp);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1408
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1409 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
1410 header[i].value.len, tmp);
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1413 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
1414 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1415
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1416
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1417 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1418 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
1419 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1420 off_t size, offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1421 size_t rest, frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1422 ngx_chain_t *cl, *out, **ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1423 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1424 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1425 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
1426 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
1427 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1428
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1429 r = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1430 stream = r->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1431
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1432 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1433 size = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1434 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1435
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1436 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
1437 "http2 send chain: %p", in);
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1438
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1439 while (in) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1440 size = ngx_buf_size(in->buf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1441
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1442 if (size || in->buf->last_buf) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1443 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1446 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1447 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1448
7235
c2a0a838c40f gRPC: special handling of "trailer only" responses.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7229
diff changeset
1449 if (in == NULL || stream->out_closed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1450
7537
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
1451 if (size) {
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
1452 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
1453 "output on closed stream");
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
1454 return NGX_CHAIN_ERROR;
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
1455 }
01e26357916a HTTP/2: return error on output on closed stream.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
1456
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1457 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
1458 return NGX_CHAIN_ERROR;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1461 return NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1464 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1465
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1466 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
1467
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1468 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
1469 return NGX_CHAIN_ERROR;
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
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1472 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
1473 fc->write->active = 1;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1474 fc->write->ready = 0;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1475 return in;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1476 }
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1479 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
1480 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1481 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1482 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1485 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1486 in->buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1487
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1488 offset = ngx_buf_in_memory(in->buf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1489 ? (cl->buf->pos - in->buf->pos)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1490 : (cl->buf->file_pos - in->buf->file_pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1491
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1492 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1493 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1494
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1495 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1496 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1497 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1498
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1499 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
1500 limit = h2c->send_window;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1503 if (limit > stream->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1504 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
1505 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1506
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1507 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
1508
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1509 frame_size = (h2lcf->chunk_size < h2c->frame_size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1510 ? h2lcf->chunk_size : h2c->frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1511
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1512 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
1513
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1514 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1515 cl = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1516 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1517
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1518 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1519 if ((off_t) frame_size > limit) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1520 frame_size = (size_t) limit;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1523 ln = &out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1524 rest = frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1525
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1526 while ((off_t) rest >= size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1527
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1528 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1529 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
1530 offset, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1531 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1532 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1535 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1536
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1537 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1538 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1539 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1540 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1541 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1542
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1543 cl->buf = in->buf;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1546 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1547 ln = &cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1548
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1549 rest -= (size_t) size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1550 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1551
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1552 if (in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1553 frame_size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1554 rest = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1555 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1558 size = ngx_buf_size(in->buf);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1561 if (rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1562 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
1563 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1564 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1567 cl->buf->flush = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1568 cl->buf->last_buf = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1569
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1570 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1571
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1572 offset += rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1573 size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1574 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1575
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1576 if (cl->buf->last_buf) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1577 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
1578 if (trailers == NULL) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1579 return NGX_CHAIN_ERROR;
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
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1582 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
1583 cl->buf->last_buf = 0;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1584 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1585 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1586
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1587 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
1588 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
1589 out, cl);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1590 if (frame == NULL) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1591 return NGX_CHAIN_ERROR;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1592 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1593
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1594 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
1595
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1596 h2c->send_window -= frame_size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1597
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1598 stream->send_window -= frame_size;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1599 stream->queued++;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1600 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1601
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1602 if (in == NULL) {
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1603
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1604 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
1605 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
1606 stream->queued++;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1607 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1608
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1609 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1612 limit -= frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1613
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1614 if (limit == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1615 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1619 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1620 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
1621 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1622 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1625 in->buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1626 ngx_free_chain(r->pool, cl);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1629 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
1630 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1633 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
1634 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1635 fc->write->ready = 0;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1638 return in;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1642 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1643 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
1644 off_t offset, off_t size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1645 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1646 ngx_buf_t *chunk;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1647 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1648
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1649 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
1650 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1651 return NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1654 chunk = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1655
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1656 ngx_memcpy(chunk, buf, sizeof(ngx_buf_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1657
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1658 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
1659 chunk->shadow = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1660
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1661 if (ngx_buf_in_memory(chunk)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1662 chunk->pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1663 chunk->last = chunk->pos + size;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1666 if (chunk->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1667 chunk->file_pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1668 chunk->file_last = chunk->file_pos + size;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1671 return cl;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1675 static ngx_http_v2_out_frame_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1676 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
1677 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
1678 {
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1679 u_char flags;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1680 ngx_buf_t *buf;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1681 ngx_chain_t *cl;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1682 ngx_http_v2_out_frame_t *frame;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1683 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1684
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1685 frame = stream->free_frames;
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1686 h2c = stream->connection;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1687
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1688 if (frame) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1689 stream->free_frames = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1690
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1691 } else if (h2c->frames < 10000) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1692 frame = ngx_palloc(stream->request->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1693 sizeof(ngx_http_v2_out_frame_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1694 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1695 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1696 }
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1697
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1698 stream->frames++;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1699 h2c->frames++;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1700
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1701 } else {
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1702 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
1703 "http2 flood detected");
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1704
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1705 h2c->connection->error = 1;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7537
diff changeset
1706 return NULL;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1709 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
1710
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1711 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
1712 "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
1713 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
1714
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1715 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
1716 &stream->free_frame_headers);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1717 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1718 return NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1721 buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1722
6600
6f69e3c0f780 HTTP/2: style.
Piotr Sikora <piotrsikora@google.com>
parents: 6593
diff changeset
1723 if (buf->start == NULL) {
6251
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1724 buf->start = ngx_palloc(stream->request->pool,
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1725 NGX_HTTP_V2_FRAME_HEADER_SIZE);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1726 if (buf->start == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1727 return NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1730 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
1731 buf->last = buf->end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1732
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1733 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
1734 buf->memory = 1;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1737 buf->pos = buf->start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1738 buf->last = buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1739
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1740 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
1741 NGX_HTTP_V2_DATA_FRAME);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1742 *buf->last++ = flags;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1743
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1744 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
1745
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1746 cl->next = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1747 first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1748
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1749 last->buf->flush = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1750
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1751 frame->first = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1752 frame->last = last;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1753 frame->handler = ngx_http_v2_data_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1754 frame->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1755 frame->length = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1756 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1757 frame->fin = last->buf->last_buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1758
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1759 return frame;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1763 static ngx_inline ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1764 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
1765 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1766 {
6792
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1767 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
1768 "http2:%ui windows: conn:%uz stream:%z",
6792
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1769 stream->node->id, h2c->send_window, stream->send_window);
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1770
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1771 if (stream->send_window <= 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1772 stream->exhausted = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1773 return NGX_DECLINED;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1776 if (h2c->send_window == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1777 ngx_http_v2_waiting_queue(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1778 return NGX_DECLINED;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1781 return NGX_OK;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1785 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1786 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
1787 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1788 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1789 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1790 ngx_http_v2_stream_t *s;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1791
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1792 if (stream->waiting) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1793 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1794 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1795
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1796 stream->waiting = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1797
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1798 for (q = ngx_queue_last(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1799 q != ngx_queue_sentinel(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1800 q = ngx_queue_prev(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1801 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1802 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
1803
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1804 if (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->rank == stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1806 && s->node->rel_weight >= stream->node->rel_weight))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1807 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1808 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1812 ngx_queue_insert_after(q, &stream->queue);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1815
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1816 static ngx_inline ngx_int_t
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1817 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
1818 {
8006
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1819 ngx_connection_t *c;
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1820
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1821 c = stream->connection->connection;
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1822
32b0ba4855a6 HTTP/2: made it possible to flush response headers (ticket #1743).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7975
diff changeset
1823 if (stream->queued == 0 && !c->buffered) {
7975
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1824 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1825 return NGX_OK;
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1826 }
a7a77549265e HTTP/2: fixed sendfile() aio handling.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7569
diff changeset
1827
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1828 stream->blocked = 1;
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 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
1831 fc->error = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1832 return NGX_ERROR;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1833 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1834
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1835 stream->blocked = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1836
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1837 if (stream->queued) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1838 fc->buffered |= NGX_HTTP_V2_BUFFERED;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1839 fc->write->active = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1840 fc->write->ready = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1841 return NGX_AGAIN;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1844 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1845
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1846 return NGX_OK;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1847 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1848
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1849
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1850 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1851 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
1852 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1853 {
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1854 ngx_chain_t *cl, *ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1855 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1856
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1857 stream = frame->stream;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1858 cl = frame->first;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1859
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1860 for ( ;; ) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1861 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
1862 frame->first = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1863
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1864 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
1865 "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
1866 stream->node->id, frame);
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1867
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1868 return NGX_AGAIN;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1869 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1870
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1871 ln = cl->next;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1872
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1873 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
1874 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1875 stream->free_frame_headers = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1876
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1877 } else {
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1878 cl->next = stream->free_bufs;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1879 stream->free_bufs = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1880 }
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1881
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1882 if (cl == frame->last) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1883 break;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1884 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1885
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1886 cl = ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1887 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1888
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1889 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
1890 "http2:%ui HEADERS frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1891 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1892
6953
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1893 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
1894 + frame->length;
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1895
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1896 h2c->payload_bytes += frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1897
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1898 ngx_http_v2_handle_frame(stream, frame);
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 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1901
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1902 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1903 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1904
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1905
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1906 static ngx_int_t
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1907 ngx_http_v2_push_frame_handler(ngx_http_v2_connection_t *h2c,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1908 ngx_http_v2_out_frame_t *frame)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1909 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1910 ngx_chain_t *cl, *ln;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1911 ngx_http_v2_stream_t *stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1912
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1913 stream = frame->stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1914 cl = frame->first;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1915
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1916 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1917 if (cl->buf->pos != cl->buf->last) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1918 frame->first = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1919
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1920 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1921 "http2:%ui PUSH_PROMISE frame %p was sent partially",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1922 stream->node->id, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1923
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1924 return NGX_AGAIN;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1925 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1926
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1927 ln = cl->next;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1928
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1929 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1930 cl->next = stream->free_frame_headers;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1931 stream->free_frame_headers = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1932
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1933 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1934 cl->next = stream->free_bufs;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1935 stream->free_bufs = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1936 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1937
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1938 if (cl == frame->last) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1939 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1940 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1941
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1942 cl = ln;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1943 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1944
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1945 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1946 "http2:%ui PUSH_PROMISE frame %p was sent",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1947 stream->node->id, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1948
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1949 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1950 + frame->length;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1951
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1952 h2c->payload_bytes += frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
1953
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1954 ngx_http_v2_handle_frame(stream, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1955
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1956 ngx_http_v2_handle_stream(h2c, stream);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1957
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1958 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1959 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1960
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1961
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1962 static ngx_int_t
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1963 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
1964 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1965 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1966 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1967 ngx_chain_t *cl, *ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1968 ngx_http_v2_stream_t *stream;
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 stream = frame->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1971 cl = frame->first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1972
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1973 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
1974
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1975 if (cl->buf->pos != cl->buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1976 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
1977 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1978 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1979
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1980 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1981 }
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 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1984
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1985 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1986 stream->free_frame_headers = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1987
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1988 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1989 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1990 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1991
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1992 cl = ln;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1995 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1996 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
1997 buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1998
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1999 if (ngx_buf_in_memory(buf)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2000 buf->pos = cl->buf->pos;
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 (buf->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2004 buf->file_pos = cl->buf->file_pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2005 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2006 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2007
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2008 if (ngx_buf_size(cl->buf) != 0) {
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 if (cl != frame->first) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2011 frame->first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2012 ngx_http_v2_handle_stream(h2c, stream);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2015 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
2016 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2017 stream->node->id, frame);
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 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2020 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2021
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2022 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2023
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2024 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
2025 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2026 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2027
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2028 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2029 ngx_free_chain(stream->request->pool, cl);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2032 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2033 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2034 }
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 cl = ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2037 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2038
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2039 done:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2040
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2041 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
2042 "http2:%ui DATA frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2043 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2044
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2045 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
2046
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2047 h2c->payload_bytes += frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2048
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2049 ngx_http_v2_handle_frame(stream, frame);
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 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2052
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2053 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2054 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2055
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2056
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2057 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2058 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
2059 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2060 {
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2061 ngx_http_request_t *r;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2062 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2063
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2064 r = stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2065
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2066 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
2067
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2068 h2c = stream->connection;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2069
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7548
diff changeset
2070 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
2071
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2072 if (frame->fin) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2073 stream->out_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2074 }
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 frame->next = stream->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2077 stream->free_frames = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2078
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2079 stream->queued--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2080 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2081
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2082
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2083 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2084 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
2085 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2086 {
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2087 ngx_event_t *wev;
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2088 ngx_connection_t *fc;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2089
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2090 if (stream->waiting || stream->blocked) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2091 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2092 }
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 fc = stream->request->connection;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2095
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2096 if (!fc->error && stream->exhausted) {
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2097 return;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2098 }
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2099
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2100 wev = fc->write;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2101
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2102 wev->active = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2103 wev->ready = 1;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2104
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2105 if (!fc->error && wev->delayed) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2106 return;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2107 }
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2108
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2109 ngx_post_event(wev, &ngx_posted_events);
6246
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
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 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2114 ngx_http_v2_filter_cleanup(void *data)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2115 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2116 ngx_http_v2_stream_t *stream = data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2117
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2118 size_t window;
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2119 ngx_event_t *wev;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2120 ngx_queue_t *q;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2121 ngx_http_v2_out_frame_t *frame, **fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2122 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2123
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2124 if (stream->waiting) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2125 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2126 ngx_queue_remove(&stream->queue);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2129 if (stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2130 return;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2133 window = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2134 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2135 fn = &h2c->last_out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2136
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2137 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2138 frame = *fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2139
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2140 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2141 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2142 }
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 (frame->stream == stream && !frame->blocked) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2145 *fn = frame->next;
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 window += frame->length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2148
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2149 if (--stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2150 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2151 }
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 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2154 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2155
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2156 fn = &frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2157 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2158
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2159 if (h2c->send_window == 0 && window) {
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 while (!ngx_queue_empty(&h2c->waiting)) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2162 q = ngx_queue_head(&h2c->waiting);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2163
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2164 ngx_queue_remove(q);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2165
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2166 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
2167
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2168 stream->waiting = 0;
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 wev = stream->request->connection->write;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2171
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2172 wev->active = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2173 wev->ready = 1;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2174
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2175 if (!wev->delayed) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2176 ngx_post_event(wev, &ngx_posted_events);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2177 }
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2178 }
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2181 h2c->send_window += window;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2184
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2185 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2186 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
2187 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2188 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
2189 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
2190
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2191 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2192 }