annotate src/http/v2/ngx_http_v2_filter_module.c @ 7229:87e9e4aabf1b

HTTP/2: externalized various constants and interfaces.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 17 Mar 2018 23:04:20 +0300
parents 3d2b0b02bd3d
children c2a0a838c40f
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;
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
139 ngx_uint_t i, port;
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
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
646 frame = ngx_http_v2_create_headers_frame(r, start, pos, r->header_only);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
647 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
648 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
649 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
650
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
651 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
652
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
653 stream->queued++;
7004
b624fbf7bee2 HTTP/2: fixed segfault when memory allocation failed.
Valentin Bartenev <vbart@nginx.com>
parents: 6953
diff changeset
654
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
655 cln = ngx_http_cleanup_add(r, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
656 if (cln == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
657 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
658 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
659
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
660 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
661 cln->data = stream;
6246
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 fc->send_chain = ngx_http_v2_send_chain;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
664 fc->need_last_buf = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
665
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
666 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
667 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
668
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
669
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
670 static ngx_int_t
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
671 ngx_http_v2_push_resources(ngx_http_request_t *r)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
672 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
673 u_char *start, *end, *last;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
674 ngx_int_t rc;
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
675 ngx_str_t path;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
676 ngx_uint_t i, push;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
677 ngx_table_elt_t **h;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
678 ngx_http_v2_loc_conf_t *h2lcf;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
679 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
680 ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS];
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
681
7202
a49af443656f HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents: 7201
diff changeset
682 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
683 "http2 push resources");
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
684
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
685 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
686
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
687 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
688
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
689 if (h2lcf->pushes) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
690 pushes = h2lcf->pushes->elts;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
691
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
692 for (i = 0; i < h2lcf->pushes->nelts; i++) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
693
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
694 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
695 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
696 }
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 (path.len == 0) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
699 continue;
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 == 3 && ngx_strncmp(path.data, "off", 3) == 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
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
706 rc = ngx_http_v2_push_resource(r, &path, binary);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
707
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
708 if (rc == NGX_ERROR) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
709 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
710 }
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_ABORT) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
713 return NGX_OK;
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 /* NGX_OK, NGX_DECLINED */
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
717 }
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 if (!h2lcf->push_preload) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
721 return NGX_OK;
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 h = r->headers_out.link.elts;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
725
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
726 for (i = 0; i < r->headers_out.link.nelts; i++) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
727
7202
a49af443656f HTTP/2: fixed build with -Werror=unused-but-set-variable.
Ruslan Ermilov <ru@nginx.com>
parents: 7201
diff changeset
728 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
729 "http2 parse link: \"%V\"", &h[i]->value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
730
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
731 start = h[i]->value.data;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
732 end = h[i]->value.data + h[i]->value.len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
733
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
734 next_link:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
735
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
736 while (start < end && *start == ' ') { start++; }
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 if (start == end || *start++ != '<') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
739 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
740 }
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 while (start < end && *start == ' ') { start++; }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
743
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
744 for (last = start; last < end && *last != '>'; last++) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
745 /* void */
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
746 }
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 if (last == start || last == end) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
749 continue;
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 path.len = last - start;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
753 path.data = start;
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 start = last + 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
756
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
757 while (start < end && *start == ' ') { 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 if (start == end) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
760 continue;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
761 }
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 == ',') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
764 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
765 goto next_link;
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
768 if (*start++ != ';') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
769 continue;
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 last = ngx_strlchr(start, end, ',');
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
773
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
774 if (last == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
775 last = end;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
776 }
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 push = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
779
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
780 for ( ;; ) {
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 while (start < last && *start == ' ') { start++; }
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 if (last - start >= 6
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
785 && ngx_strncasecmp(start, (u_char *) "nopush", 6) == 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
786 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
787 start += 6;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
788
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
789 if (start == last || *start == ' ' || *start == ';') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
790 push = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
791 break;
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
794 goto next_param;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
795 }
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 if (last - start >= 11
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
798 && ngx_strncasecmp(start, (u_char *) "rel=preload", 11) == 0)
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 start += 11;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
801
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
802 if (start == last || *start == ' ' || *start == ';') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
803 push = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
804 }
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 goto next_param;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
807 }
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 if (last - start >= 4
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
810 && ngx_strncasecmp(start, (u_char *) "rel=", 4) == 0)
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 start += 4;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
813
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
814 while (start < last && *start == ' ') { start++; }
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 if (start == last || *start++ != '"') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
817 goto next_param;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
818 }
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 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
821
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
822 while (start < last && *start == ' ') { start++; }
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 if (last - start >= 7
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
825 && ngx_strncasecmp(start, (u_char *) "preload", 7) == 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
826 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
827 start += 7;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
828
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
829 if (start < last && (*start == ' ' || *start == '"')) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
830 push = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
831 break;
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 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
834
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
835 while (start < last && *start != ' ' && *start != '"') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
836 start++;
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 if (start == last) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
840 break;
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 == '"') {
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 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
848 }
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 next_param:
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 start = ngx_strlchr(start, last, ';');
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 if (start == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
856 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
857 }
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 start++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
860 }
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 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
863 while (path.len && path.data[path.len - 1] == ' ') {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
864 path.len--;
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 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
867
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
868 if (push && path.len
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
869 && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/'))
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
870 {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
871 rc = ngx_http_v2_push_resource(r, &path, binary);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
872
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
873 if (rc == NGX_ERROR) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
874 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
875 }
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_ABORT) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
878 return NGX_OK;
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 /* NGX_OK, NGX_DECLINED */
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
882 }
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 if (last < end) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
885 start = last + 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
886 goto next_link;
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 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
889
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
890 return NGX_OK;
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 static ngx_int_t
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
895 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
896 ngx_str_t *binary)
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
897 {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
898 u_char *start, *pos, *tmp;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
899 size_t len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
900 ngx_str_t *value;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
901 ngx_uint_t i;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
902 ngx_table_elt_t **h;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
903 ngx_connection_t *fc;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
904 ngx_http_v2_stream_t *stream;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
905 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
906 ngx_http_v2_connection_t *h2c;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
907 ngx_http_v2_push_header_t *ph;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
908
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
909 fc = r->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
910
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
911 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
912
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
913 stream = r->stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
914 h2c = stream->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
915
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
916 if (!ngx_path_separator(path->data[0])) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
917 ngx_log_error(NGX_LOG_WARN, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
918 "non-absolute path \"%V\" not pushed", path);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
919 return NGX_DECLINED;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
920 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
921
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
922 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
923 "http2 pushing:%ui limit:%ui",
e44c297a6b95 HTTP/2: style.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7203
diff changeset
924 h2c->pushing, h2c->concurrent_pushes);
7201
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 if (h2c->pushing >= h2c->concurrent_pushes) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
927 return NGX_ABORT;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
928 }
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->last_push == 0x7ffffffe) {
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 (path->len > NGX_HTTP_V2_MAX_FIELD) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
935 return NGX_DECLINED;
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
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
938 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
939 return NGX_ABORT;
8b0553239592 HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7202
diff changeset
940 }
8b0553239592 HTTP/2: fixed null pointer dereference with server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7202
diff changeset
941
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
942 ph = ngx_http_v2_push_headers;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
943
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
944 if (binary[0].len) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
945 tmp = ngx_palloc(r->pool, path->len);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
946 if (tmp == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
947 return NGX_ERROR;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
948 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
949
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
950 } else {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
951 len = path->len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
952
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
953 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
954 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
955
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
956 if (*h) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
957 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
958 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
959 }
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
960
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
961 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
962 if (tmp == NULL) {
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
963 return NGX_ERROR;
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
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
966 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
967 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
968
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
969 if (*h == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
970 continue;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
971 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
972
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
973 value = &(*h)->value;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
974
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
975 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
976
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
977 pos = ngx_pnalloc(r->pool, len);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
978 if (pos == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
979 return NGX_ERROR;
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
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
982 binary[i].data = pos;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
983
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
984 *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
985 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
986
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
987 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
988 }
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
989 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
990
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
991 len = (h2c->table_update ? 1 : 0)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
992 + 1
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
993 + 1 + NGX_HTTP_V2_INT_OCTETS + path->len
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
994 + 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
995
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
996 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
997 len += binary[i].len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
998 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
999
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1000 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
1001 if (pos == NULL) {
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1002 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1003 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1004
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1005 start = pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1006
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1007 if (h2c->table_update) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1008 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1009 "http2 table size update: 0");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1010 *pos++ = (1 << 5) | 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1011 h2c->table_update = 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1012 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1013
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1014 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1015 "http2 push header: \":method: GET\"");
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 *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
1018
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1019 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1020 "http2 push header: \":path: %V\"", path);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1021
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1022 *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
1023 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
1024
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1025 #if (NGX_HTTP_SSL)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1026 if (fc->ssl) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1027 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1028 "http2 push header: \":scheme: https\"");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1029 *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
1030
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1031 } else
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1032 #endif
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1033 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1034 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1035 "http2 push header: \":scheme: http\"");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1036 *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTP_INDEX);
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
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1039 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
1040 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
1041
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1042 if (*h == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1043 continue;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1044 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1045
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1046 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
1047 "http2 push header: \"%V: %V\"",
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1048 &ph[i].name, &(*h)->value);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1049
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1050 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
1051 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1052
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1053 frame = ngx_http_v2_create_push_frame(r, start, pos);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1054 if (frame == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1055 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1056 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1057
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1058 ngx_http_v2_queue_blocked_frame(h2c, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1059
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1060 stream->queued++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1061
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1062 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
1063
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1064 if (stream) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1065 stream->request->request_length = pos - start;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1066 return NGX_OK;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1067 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1068
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
1069 return NGX_ERROR;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1070 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1071
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1072
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1073 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
1074 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
1075 u_char *end, ngx_uint_t fin)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1076 {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1077 u_char type, flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1078 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
1079 ngx_buf_t *b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1080 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
1081 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
1082 ngx_http_v2_out_frame_t *frame;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1083
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1084 stream = r->stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1085 rest = end - pos;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1086
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1087 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
1088 if (frame == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1089 return NULL;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1090 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1091
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1092 frame->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
1093 frame->stream = stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1094 frame->length = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1095 frame->blocked = 1;
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1096 frame->fin = fin;
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1097
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1098 ll = &frame->first;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1099
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1100 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
1101 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
1102 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
1103
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1104 for ( ;; ) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1105 if (rest <= frame_size) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1106 frame_size = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1107 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
1108 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1109
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1110 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
1111 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1112 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1113 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1114
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1115 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
1116 *b->last++ = flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1117 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
1118
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1119 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
1120
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1121 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
1122 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1123 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1124 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1125
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1126 cl->buf = b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1127
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1128 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1129 ll = &cl->next;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1130
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1131 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
1132 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1133 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1134 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1135
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1136 b->pos = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1137
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1138 pos += frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1139
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1140 b->last = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1141 b->start = b->pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1142 b->end = b->last;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1143 b->temporary = 1;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1144
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1145 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
1146 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1147 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1148 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1149
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1150 cl->buf = b;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1151
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1152 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1153 ll = &cl->next;
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 rest -= frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1156
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1157 if (rest) {
6952
afc60bd9008f HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6885
diff changeset
1158 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
afc60bd9008f HTTP/2: fix $bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6885
diff changeset
1159
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1160 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
1161 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
1162 continue;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1163 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1164
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1165 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
1166 cl->next = NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1167 frame->last = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1168
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1169 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1170 "http2:%ui create HEADERS frame %p: len:%uz",
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1171 stream->node->id, frame, frame->length);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1172
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1173 return frame;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
1174 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1175 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1176
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1177
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1178 static ngx_http_v2_out_frame_t *
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1179 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
1180 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1181 u_char type, flags;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1182 size_t rest, frame_size, len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1183 ngx_buf_t *b;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1184 ngx_chain_t *cl, **ll;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1185 ngx_http_v2_stream_t *stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1186 ngx_http_v2_out_frame_t *frame;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1187 ngx_http_v2_connection_t *h2c;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1188
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1189 stream = r->stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1190 h2c = stream->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1191 rest = NGX_HTTP_V2_STREAM_ID_SIZE + (end - pos);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1192
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1193 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
1194 if (frame == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1195 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1196 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1197
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1198 frame->handler = ngx_http_v2_push_frame_handler;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1199 frame->stream = stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1200 frame->length = rest;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1201 frame->blocked = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1202 frame->fin = 0;
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 ll = &frame->first;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1205
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1206 type = NGX_HTTP_V2_PUSH_PROMISE_FRAME;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1207 flags = NGX_HTTP_V2_NO_FLAG;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1208 frame_size = h2c->frame_size;
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 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1211 if (rest <= frame_size) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1212 frame_size = rest;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1213 flags |= NGX_HTTP_V2_END_HEADERS_FLAG;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1214 }
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 b = ngx_create_temp_buf(r->pool,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1217 NGX_HTTP_V2_FRAME_HEADER_SIZE
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1218 + ((type == NGX_HTTP_V2_PUSH_PROMISE_FRAME)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1219 ? NGX_HTTP_V2_STREAM_ID_SIZE : 0));
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1220 if (b == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1221 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1222 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1223
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1224 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
1225 *b->last++ = flags;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1226 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
1227
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1228 b->tag = (ngx_buf_tag_t) &ngx_http_v2_module;
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 if (type == NGX_HTTP_V2_PUSH_PROMISE_FRAME) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1231 h2c->last_push += 2;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1232
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1233 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
1234 len = frame_size - NGX_HTTP_V2_STREAM_ID_SIZE;
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 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1237 len = frame_size;
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1240 cl = ngx_alloc_chain_link(r->pool);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1241 if (cl == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1242 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1243 }
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 cl->buf = b;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1246
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1247 *ll = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1248 ll = &cl->next;
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 b = ngx_calloc_buf(r->pool);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1251 if (b == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1252 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1253 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1254
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1255 b->pos = pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1256
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1257 pos += len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1258
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1259 b->last = pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1260 b->start = b->pos;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1261 b->end = b->last;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1262 b->temporary = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1263
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1264 cl = ngx_alloc_chain_link(r->pool);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1265 if (cl == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1266 return NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1267 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1268
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1269 cl->buf = b;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1270
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1271 *ll = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1272 ll = &cl->next;
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 rest -= frame_size;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1275
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1276 if (rest) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1277 frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1278
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1279 type = NGX_HTTP_V2_CONTINUATION_FRAME;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1280 continue;
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
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1283 cl->next = NULL;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1284 frame->last = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1285
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1286 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
1287 "http2:%ui create PUSH_PROMISE frame %p: "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1288 "sid:%ui len:%uz",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1289 stream->node->id, frame, h2c->last_push,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1290 frame->length);
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 return frame;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1293 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1294 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1295
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1296
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1297 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
1298 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
1299 {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1300 u_char *pos, *start, *tmp;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1301 size_t len, tmp_len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1302 ngx_uint_t i;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1303 ngx_list_part_t *part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1304 ngx_table_elt_t *header;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1305 ngx_connection_t *fc;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1306
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1307 fc = r->connection;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1308 len = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1309 tmp_len = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1310
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1311 part = &r->headers_out.trailers.part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1312 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1313
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1314 for (i = 0; /* void */; i++) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1315
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1316 if (i >= part->nelts) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1317 if (part->next == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1318 break;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1321 part = part->next;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1322 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1323 i = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1324 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1325
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1326 if (header[i].hash == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1327 continue;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1328 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1329
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1330 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
1331 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
1332 "too long response trailer name: \"%V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1333 &header[i].key);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1334 return NULL;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1337 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
1338 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
1339 "too long response trailer value: \"%V: %V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1340 &header[i].key, &header[i].value);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1341 return NULL;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1344 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
1345 + 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
1346
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1347 if (header[i].key.len > tmp_len) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1348 tmp_len = header[i].key.len;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1351 if (header[i].value.len > tmp_len) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1352 tmp_len = header[i].value.len;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1353 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1354 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1355
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1356 if (len == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1357 return NGX_HTTP_V2_NO_TRAILERS;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1358 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1359
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1360 tmp = ngx_palloc(r->pool, tmp_len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1361 pos = ngx_pnalloc(r->pool, len);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1362
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1363 if (pos == NULL || tmp == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1364 return NULL;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1367 start = pos;
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 part = &r->headers_out.trailers.part;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1370 header = part->elts;
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 for (i = 0; /* void */; i++) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1373
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1374 if (i >= part->nelts) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1375 if (part->next == NULL) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1376 break;
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1379 part = part->next;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1380 header = part->elts;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1381 i = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1382 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1383
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1384 if (header[i].hash == 0) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1385 continue;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1386 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1387
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1388 #if (NGX_DEBUG)
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1389 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
1390 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
1391
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1392 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
1393 "http2 output trailer: \"%*s: %V\"",
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1394 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
1395 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1396 #endif
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 *pos++ = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1399
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1400 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
1401 header[i].key.len, tmp);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1402
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1403 pos = 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
1404 header[i].value.len, tmp);
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
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1407 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
1408 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1409
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1410
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1411 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1412 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
1413 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1414 off_t size, offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1415 size_t rest, frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1416 ngx_chain_t *cl, *out, **ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1417 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1418 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1419 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
1420 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
1421 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1422
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1423 r = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1424 stream = r->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1425
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1426 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1427 size = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1428 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1429
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1430 while (in) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1431 size = ngx_buf_size(in->buf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1432
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1433 if (size || in->buf->last_buf) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1434 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1435 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1436
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1437 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1438 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1439
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1440 if (in == NULL) {
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 (stream->queued) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1443 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1444 fc->write->ready = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1445
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1446 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1447 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1448 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1449
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1450 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1451 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1452
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1453 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1454
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1455 if (size && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1456 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1457 fc->write->ready = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1458 return in;
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 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
1462 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1463 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1464 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1467 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1468 in->buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1469
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1470 offset = ngx_buf_in_memory(in->buf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1471 ? (cl->buf->pos - in->buf->pos)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1472 : (cl->buf->file_pos - in->buf->file_pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1473
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1474 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1475 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1476
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1477 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1478 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1479 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1480
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1481 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
1482 limit = h2c->send_window;
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 if (limit > stream->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1486 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
1487 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1488
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1489 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
1490
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1491 frame_size = (h2lcf->chunk_size < h2c->frame_size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1492 ? h2lcf->chunk_size : h2c->frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1493
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1494 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
1495
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1496 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1497 cl = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1498 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1499
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1500 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1501 if ((off_t) frame_size > limit) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1502 frame_size = (size_t) limit;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1503 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1504
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1505 ln = &out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1506 rest = frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1507
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1508 while ((off_t) rest >= size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1509
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1510 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1511 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
1512 offset, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1513 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1514 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1515 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1516
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1517 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1518
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1519 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1520 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1521 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1522 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1523 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1524
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1525 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1526 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1527
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1528 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1529 ln = &cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1530
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1531 rest -= (size_t) size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1532 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1533
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1534 if (in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1535 frame_size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1536 rest = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1537 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1538 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1539
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1540 size = ngx_buf_size(in->buf);
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 if (rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1544 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
1545 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1546 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1547 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1548
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1549 cl->buf->flush = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1550 cl->buf->last_buf = 0;
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 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1553
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1554 offset += rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1555 size -= rest;
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
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1558 if (cl->buf->last_buf) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1559 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
1560 if (trailers == NULL) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1561 return NGX_CHAIN_ERROR;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1562 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1563
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1564 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
1565 cl->buf->last_buf = 0;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1566 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1567 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1568
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1569 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
1570 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
1571 out, cl);
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1572 if (frame == NULL) {
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1573 return NGX_CHAIN_ERROR;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1574 }
6246
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 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
1577
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1578 h2c->send_window -= frame_size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1579
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1580 stream->send_window -= frame_size;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1581 stream->queued++;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1582 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1583
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1584 if (in == NULL) {
7035
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1585
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1586 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
1587 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
1588 stream->queued++;
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1589 }
4e784e095a97 HTTP/2: added support for trailers in HTTP responses.
Piotr Sikora <piotrsikora@google.com>
parents: 7004
diff changeset
1590
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1591 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1592 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1593
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1594 limit -= frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1595
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1596 if (limit == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1597 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1598 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1599 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1600
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1601 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1602 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
1603 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1604 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1605 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1606
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1607 in->buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1608 ngx_free_chain(r->pool, cl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1609 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1610
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1611 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
1612 return NGX_CHAIN_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1615 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
1616 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1617 fc->write->ready = 0;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1620 return in;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1621 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1622
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1623
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1624 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1625 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
1626 off_t offset, off_t size)
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 ngx_buf_t *chunk;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1629 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1630
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1631 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
1632 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1633 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1634 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1635
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1636 chunk = cl->buf;
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 ngx_memcpy(chunk, buf, sizeof(ngx_buf_t));
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 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
1641 chunk->shadow = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1642
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1643 if (ngx_buf_in_memory(chunk)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1644 chunk->pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1645 chunk->last = chunk->pos + size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1646 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1647
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1648 if (chunk->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1649 chunk->file_pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1650 chunk->file_last = chunk->file_pos + size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1651 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1652
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1653 return cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1654 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1655
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1656
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1657 static ngx_http_v2_out_frame_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1658 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
1659 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
1660 {
6600
6f69e3c0f780 HTTP/2: style.
Piotr Sikora <piotrsikora@google.com>
parents: 6593
diff changeset
1661 u_char flags;
6f69e3c0f780 HTTP/2: style.
Piotr Sikora <piotrsikora@google.com>
parents: 6593
diff changeset
1662 ngx_buf_t *buf;
6f69e3c0f780 HTTP/2: style.
Piotr Sikora <piotrsikora@google.com>
parents: 6593
diff changeset
1663 ngx_chain_t *cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1664 ngx_http_v2_out_frame_t *frame;
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 frame = stream->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1667
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1668 if (frame) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1669 stream->free_frames = frame->next;
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 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1672 frame = ngx_palloc(stream->request->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1673 sizeof(ngx_http_v2_out_frame_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1674 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1675 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1676 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1677 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1678
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1679 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
1680
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1681 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
1682 "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
1683 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
1684
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1685 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
1686 &stream->free_frame_headers);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1687 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1688 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1689 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1690
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1691 buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1692
6600
6f69e3c0f780 HTTP/2: style.
Piotr Sikora <piotrsikora@google.com>
parents: 6593
diff changeset
1693 if (buf->start == NULL) {
6251
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1694 buf->start = ngx_palloc(stream->request->pool,
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1695 NGX_HTTP_V2_FRAME_HEADER_SIZE);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1696 if (buf->start == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1697 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1698 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1699
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1700 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
1701 buf->last = buf->end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1702
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1703 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
1704 buf->memory = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1705 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1706
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1707 buf->pos = buf->start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1708 buf->last = buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1709
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1710 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
1711 NGX_HTTP_V2_DATA_FRAME);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1712 *buf->last++ = flags;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1713
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1714 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
1715
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1716 cl->next = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1717 first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1718
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1719 last->buf->flush = 1;
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 frame->first = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1722 frame->last = last;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1723 frame->handler = ngx_http_v2_data_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1724 frame->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1725 frame->length = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1726 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1727 frame->fin = last->buf->last_buf;
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 return frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1730 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1731
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1732
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1733 static ngx_inline ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1734 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
1735 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1736 {
6792
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1737 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
1738 "http2:%ui windows: conn:%uz stream:%z",
6792
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1739 stream->node->id, h2c->send_window, stream->send_window);
45d553812055 HTTP/2: flow control debugging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6638
diff changeset
1740
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1741 if (stream->send_window <= 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1742 stream->exhausted = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1743 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1744 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1745
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1746 if (h2c->send_window == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1747 ngx_http_v2_waiting_queue(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1748 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1749 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1750
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1751 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1752 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1753
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1754
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1755 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1756 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
1757 ngx_http_v2_stream_t *stream)
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 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1760 ngx_http_v2_stream_t *s;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1761
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1762 if (stream->waiting) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1763 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1764 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1765
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
1766 stream->waiting = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1767
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1768 for (q = ngx_queue_last(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1769 q != ngx_queue_sentinel(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1770 q = ngx_queue_prev(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1771 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1772 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
1773
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1774 if (s->node->rank < stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1775 || (s->node->rank == stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1776 && s->node->rel_weight >= stream->node->rel_weight))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1777 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1778 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1782 ngx_queue_insert_after(q, &stream->queue);
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
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1786 static ngx_inline ngx_int_t
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1787 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
1788 {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1789 stream->blocked = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1790
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1791 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
1792 fc->error = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1793 return NGX_ERROR;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1794 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1795
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1796 stream->blocked = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1797
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1798 if (stream->queued) {
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1799 fc->buffered |= NGX_HTTP_V2_BUFFERED;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1800 fc->write->active = 1;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1801 fc->write->ready = 0;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1802 return NGX_AGAIN;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1803 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1804
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1805 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1806
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1807 return NGX_OK;
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1808 }
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7108
diff changeset
1809
6246
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 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1812 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
1813 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1814 {
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1815 ngx_chain_t *cl, *ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1816 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1817
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1818 stream = frame->stream;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1819 cl = frame->first;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1820
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1821 for ( ;; ) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1822 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
1823 frame->first = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1824
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1825 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
1826 "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
1827 stream->node->id, frame);
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1828
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1829 return NGX_AGAIN;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1830 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1831
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1832 ln = cl->next;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1833
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1834 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
1835 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1836 stream->free_frame_headers = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1837
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1838 } else {
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1839 cl->next = stream->free_bufs;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1840 stream->free_bufs = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1841 }
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1842
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1843 if (cl == frame->last) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1844 break;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1845 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1846
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1847 cl = ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1848 }
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 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
1851 "http2:%ui HEADERS frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1852 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1853
6953
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1854 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
1855 + frame->length;
663e6a48bfcb HTTP/2: fix $body_bytes_sent variable.
Piotr Sikora <piotrsikora@google.com>
parents: 6952
diff changeset
1856
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1857 ngx_http_v2_handle_frame(stream, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1858
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1859 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1860
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1861 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1862 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1863
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1864
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1865 static ngx_int_t
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1866 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
1867 ngx_http_v2_out_frame_t *frame)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1868 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1869 ngx_chain_t *cl, *ln;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1870 ngx_http_v2_stream_t *stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1871
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1872 stream = frame->stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1873 cl = frame->first;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1874
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1875 for ( ;; ) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1876 if (cl->buf->pos != cl->buf->last) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1877 frame->first = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1878
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1879 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
1880 "http2:%ui PUSH_PROMISE frame %p was sent partially",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1881 stream->node->id, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1882
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1883 return NGX_AGAIN;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1884 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1885
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1886 ln = cl->next;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1887
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1888 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
1889 cl->next = stream->free_frame_headers;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1890 stream->free_frame_headers = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1891
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1892 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1893 cl->next = stream->free_bufs;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1894 stream->free_bufs = cl;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1895 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1896
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1897 if (cl == frame->last) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1898 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1899 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1900
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1901 cl = ln;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1902 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1903
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1904 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
1905 "http2:%ui PUSH_PROMISE frame %p was sent",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1906 stream->node->id, frame);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1907
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1908 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1909 + frame->length;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1910
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1911 ngx_http_v2_handle_frame(stream, frame);
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 ngx_http_v2_handle_stream(h2c, stream);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1914
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1915 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1916 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1917
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1918
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1919 static ngx_int_t
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1920 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
1921 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1922 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1923 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1924 ngx_chain_t *cl, *ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1925 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1926
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1927 stream = frame->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1928 cl = frame->first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1929
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1930 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
1931
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1932 if (cl->buf->pos != cl->buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1933 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
1934 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1935 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1936
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1937 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1938 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1939
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1940 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1941
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1942 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1943 stream->free_frame_headers = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1944
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1945 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1946 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1947 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1948
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1949 cl = ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1950 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1951
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1952 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1953 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
1954 buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1955
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1956 if (ngx_buf_in_memory(buf)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1957 buf->pos = cl->buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1958 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1959
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1960 if (buf->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1961 buf->file_pos = cl->buf->file_pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1962 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1963 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1964
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1965 if (ngx_buf_size(cl->buf) != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1966
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1967 if (cl != frame->first) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1968 frame->first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1969 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1970 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1971
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1972 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
1973 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1974 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1975
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1976 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1977 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1978
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1979 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1980
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1981 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
1982 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1983 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1984
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1985 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1986 ngx_free_chain(stream->request->pool, cl);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1989 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1990 goto done;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1993 cl = ln;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1996 done:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1997
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1998 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
1999 "http2:%ui DATA frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2000 stream->node->id, frame);
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 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
2003
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2004 ngx_http_v2_handle_frame(stream, frame);
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 ngx_http_v2_handle_stream(h2c, stream);
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 return NGX_OK;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2011
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2012 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2013 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
2014 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2015 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2016 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2017
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2018 r = stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2019
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2020 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
2021
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2022 if (frame->fin) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2023 stream->out_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2024 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2025
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2026 frame->next = stream->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2027 stream->free_frames = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2028
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2029 stream->queued--;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2033 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2034 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
2035 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2036 {
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2037 ngx_event_t *wev;
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2038 ngx_connection_t *fc;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2039
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2040 if (stream->waiting || stream->blocked) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2041 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2042 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2043
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2044 fc = stream->request->connection;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2045
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2046 if (!fc->error && stream->exhausted) {
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2047 return;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2048 }
6638
a2b310a8b2af HTTP/2: always handle streams in error state.
Valentin Bartenev <vbart@nginx.com>
parents: 6637
diff changeset
2049
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2050 wev = fc->write;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2051
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2052 wev->active = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2053 wev->ready = 1;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2054
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2055 if (!fc->error && wev->delayed) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2056 return;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2057 }
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2058
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2059 ngx_post_event(wev, &ngx_posted_events);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2060 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2061
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2062
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2063 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2064 ngx_http_v2_filter_cleanup(void *data)
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 ngx_http_v2_stream_t *stream = data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2067
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2068 size_t window;
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2069 ngx_event_t *wev;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2070 ngx_queue_t *q;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2071 ngx_http_v2_out_frame_t *frame, **fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2072 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2073
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2074 if (stream->waiting) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2075 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2076 ngx_queue_remove(&stream->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2077 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2078
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2079 if (stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2080 return;
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 window = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2084 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2085 fn = &h2c->last_out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2086
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2087 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2088 frame = *fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2089
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2090 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2091 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2094 if (frame->stream == stream && !frame->blocked) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2095 *fn = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2096
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2097 window += frame->length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2098
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2099 if (--stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2100 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2101 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2102
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2103 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2104 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2105
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2106 fn = &frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2107 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2108
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2109 if (h2c->send_window == 0 && window) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2110
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2111 while (!ngx_queue_empty(&h2c->waiting)) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2112 q = ngx_queue_head(&h2c->waiting);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2113
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2114 ngx_queue_remove(q);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2115
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2116 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
2117
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2118 stream->waiting = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2119
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2120 wev = stream->request->connection->write;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2121
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2122 wev->active = 0;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2123 wev->ready = 1;
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2124
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2125 if (!wev->delayed) {
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2126 ngx_post_event(wev, &ngx_posted_events);
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2127 }
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6792
diff changeset
2128 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2129 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2130
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2131 h2c->send_window += window;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2134
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2135 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2136 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
2137 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2138 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
2139 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
2140
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2141 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2142 }