annotate src/http/v2/ngx_http_v2.c @ 7201:641306096f5b

HTTP/2: server push. Resources to be pushed are configured with the "http2_push" directive. Also, preload links from the Link response headers, as described in https://www.w3.org/TR/preload/#server-push-http-2, can be pushed, if enabled with the "http2_push_preload" directive. Only relative URIs with absolute paths can be pushed. The number of concurrent pushes is normally limited by a client, but cannot exceed a hard limit set by the "http2_max_concurrent_pushes" directive.
author Ruslan Ermilov <ru@nginx.com>
date Thu, 08 Feb 2018 09:55:03 +0300
parents cadb43014c7c
children e44c297a6b95
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
5 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
6
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
7
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
10 #include <ngx_http.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
11 #include <ngx_http_v2_module.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
12
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
13
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
14 /* errors */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
15 #define NGX_HTTP_V2_NO_ERROR 0x0
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
16 #define NGX_HTTP_V2_PROTOCOL_ERROR 0x1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
17 #define NGX_HTTP_V2_INTERNAL_ERROR 0x2
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
18 #define NGX_HTTP_V2_FLOW_CTRL_ERROR 0x3
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
19 #define NGX_HTTP_V2_SETTINGS_TIMEOUT 0x4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
20 #define NGX_HTTP_V2_STREAM_CLOSED 0x5
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
21 #define NGX_HTTP_V2_SIZE_ERROR 0x6
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
22 #define NGX_HTTP_V2_REFUSED_STREAM 0x7
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
23 #define NGX_HTTP_V2_CANCEL 0x8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
24 #define NGX_HTTP_V2_COMP_ERROR 0x9
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
25 #define NGX_HTTP_V2_CONNECT_ERROR 0xa
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
26 #define NGX_HTTP_V2_ENHANCE_YOUR_CALM 0xb
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
27 #define NGX_HTTP_V2_INADEQUATE_SECURITY 0xc
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
28 #define NGX_HTTP_V2_HTTP_1_1_REQUIRED 0xd
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
29
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
30 /* frame sizes */
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
31 #define NGX_HTTP_V2_SETTINGS_ACK_SIZE 0
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
32 #define NGX_HTTP_V2_RST_STREAM_SIZE 4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
33 #define NGX_HTTP_V2_PRIORITY_SIZE 5
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
34 #define NGX_HTTP_V2_PING_SIZE 8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
35 #define NGX_HTTP_V2_GOAWAY_SIZE 8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
36 #define NGX_HTTP_V2_WINDOW_UPDATE_SIZE 4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
37
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
38 #define NGX_HTTP_V2_SETTINGS_PARAM_SIZE 6
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
39
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
40 /* settings fields */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
41 #define NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING 0x1
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
42 #define NGX_HTTP_V2_ENABLE_PUSH_SETTING 0x2
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
43 #define NGX_HTTP_V2_MAX_STREAMS_SETTING 0x3
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
44 #define NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING 0x4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
45 #define NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING 0x5
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
46
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
47 #define NGX_HTTP_V2_FRAME_BUFFER_SIZE 24
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
48
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
49 #define NGX_HTTP_V2_DEFAULT_FRAME_SIZE (1 << 14)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
50
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
51 #define NGX_HTTP_V2_ROOT (void *) -1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
52
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
53
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
54 static void ngx_http_v2_read_handler(ngx_event_t *rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
55 static void ngx_http_v2_write_handler(ngx_event_t *wev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
56 static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
57
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
58 static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
59 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
60 static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
61 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
62 static u_char *ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
63 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
64 static u_char *ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
65 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
66 static u_char *ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
67 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
68 static u_char *ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
69 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
70 static u_char *ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
71 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
72 static u_char *ngx_http_v2_state_header_block(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
73 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
74 static u_char *ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
75 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
76 static u_char *ngx_http_v2_state_field_huff(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
77 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
78 static u_char *ngx_http_v2_state_field_raw(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
79 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
80 static u_char *ngx_http_v2_state_field_skip(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
81 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
82 static u_char *ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
83 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
84 static u_char *ngx_http_v2_state_header_complete(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
85 u_char *pos, u_char *end);
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
86 static u_char *ngx_http_v2_handle_continuation(ngx_http_v2_connection_t *h2c,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
87 u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
88 static u_char *ngx_http_v2_state_priority(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
89 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
90 static u_char *ngx_http_v2_state_rst_stream(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
91 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
92 static u_char *ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
93 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
94 static u_char *ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
95 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
96 static u_char *ngx_http_v2_state_push_promise(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
97 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
98 static u_char *ngx_http_v2_state_ping(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
99 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
100 static u_char *ngx_http_v2_state_goaway(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
101 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
102 static u_char *ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
103 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
104 static u_char *ngx_http_v2_state_continuation(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
105 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
106 static u_char *ngx_http_v2_state_complete(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
107 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
108 static u_char *ngx_http_v2_state_skip_padded(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
109 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
110 static u_char *ngx_http_v2_state_skip(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
111 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
112 static u_char *ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
113 u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
114 static u_char *ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
115 u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
116 static u_char *ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
117 ngx_uint_t err);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
118
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
119 static ngx_int_t ngx_http_v2_parse_int(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
120 u_char **pos, u_char *end, ngx_uint_t prefix);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
121
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
122 static ngx_http_v2_stream_t *ngx_http_v2_create_stream(
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
123 ngx_http_v2_connection_t *h2c, ngx_uint_t push);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
124 static ngx_http_v2_node_t *ngx_http_v2_get_node_by_id(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
125 ngx_http_v2_connection_t *h2c, ngx_uint_t sid, ngx_uint_t alloc);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
126 static ngx_http_v2_node_t *ngx_http_v2_get_closed_node(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
127 ngx_http_v2_connection_t *h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
128 #define ngx_http_v2_index_size(h2scf) (h2scf->streams_index_mask + 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
129 #define ngx_http_v2_index(h2scf, sid) ((sid >> 1) & h2scf->streams_index_mask)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
130
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
131 static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
132 static ngx_int_t ngx_http_v2_settings_frame_handler(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
133 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
134 static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
135 ngx_uint_t sid, size_t window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
136 static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
137 ngx_uint_t sid, ngx_uint_t status);
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
138 static ngx_int_t ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c,
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
139 ngx_uint_t status);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
140
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
141 static ngx_http_v2_out_frame_t *ngx_http_v2_get_frame(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
142 ngx_http_v2_connection_t *h2c, size_t length, ngx_uint_t type,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
143 u_char flags, ngx_uint_t sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
144 static ngx_int_t ngx_http_v2_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
145 ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
146
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
147 static ngx_int_t ngx_http_v2_validate_header(ngx_http_request_t *r,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
148 ngx_http_v2_header_t *header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
149 static ngx_int_t ngx_http_v2_pseudo_header(ngx_http_request_t *r,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
150 ngx_http_v2_header_t *header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
151 static ngx_int_t ngx_http_v2_parse_path(ngx_http_request_t *r,
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
152 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
153 static ngx_int_t ngx_http_v2_parse_method(ngx_http_request_t *r,
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
154 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
155 static ngx_int_t ngx_http_v2_parse_scheme(ngx_http_request_t *r,
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
156 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
157 static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r,
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
158 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
159 static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
160 static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
161 ngx_http_v2_header_t *header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
162 static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
163 static void ngx_http_v2_run_request(ngx_http_request_t *r);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
164 static void ngx_http_v2_run_request_handler(ngx_event_t *ev);
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
165 static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
166 u_char *pos, size_t size, ngx_uint_t last);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
167 static ngx_int_t ngx_http_v2_filter_request_body(ngx_http_request_t *r);
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
168 static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r);
6246
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 static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
171 ngx_http_v2_stream_t *stream, ngx_uint_t status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
172 static void ngx_http_v2_close_stream_handler(ngx_event_t *ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
173 static void ngx_http_v2_handle_connection_handler(ngx_event_t *rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
174 static void ngx_http_v2_idle_handler(ngx_event_t *rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
175 static void ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
176 ngx_uint_t status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
177
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
178 static ngx_int_t ngx_http_v2_adjust_windows(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
179 ssize_t delta);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
180 static void ngx_http_v2_set_dependency(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
181 ngx_http_v2_node_t *node, ngx_uint_t depend, ngx_uint_t exclusive);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
182 static void ngx_http_v2_node_children_update(ngx_http_v2_node_t *node);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
183
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
184 static void ngx_http_v2_pool_cleanup(void *data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
185
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
186
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
187 static ngx_http_v2_handler_pt ngx_http_v2_frame_states[] = {
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
188 ngx_http_v2_state_data, /* NGX_HTTP_V2_DATA_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
189 ngx_http_v2_state_headers, /* NGX_HTTP_V2_HEADERS_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
190 ngx_http_v2_state_priority, /* NGX_HTTP_V2_PRIORITY_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
191 ngx_http_v2_state_rst_stream, /* NGX_HTTP_V2_RST_STREAM_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
192 ngx_http_v2_state_settings, /* NGX_HTTP_V2_SETTINGS_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
193 ngx_http_v2_state_push_promise, /* NGX_HTTP_V2_PUSH_PROMISE_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
194 ngx_http_v2_state_ping, /* NGX_HTTP_V2_PING_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
195 ngx_http_v2_state_goaway, /* NGX_HTTP_V2_GOAWAY_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
196 ngx_http_v2_state_window_update, /* NGX_HTTP_V2_WINDOW_UPDATE_FRAME */
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
197 ngx_http_v2_state_continuation /* NGX_HTTP_V2_CONTINUATION_FRAME */
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
200 #define NGX_HTTP_V2_FRAME_STATES \
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
201 (sizeof(ngx_http_v2_frame_states) / sizeof(ngx_http_v2_handler_pt))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
202
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 void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
205 ngx_http_v2_init(ngx_event_t *rev)
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 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
208 ngx_pool_cleanup_t *cln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
209 ngx_http_connection_t *hc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
210 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
211 ngx_http_v2_main_conf_t *h2mcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
212 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
213
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
214 c = rev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
215 hc = c->data;
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 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "init http2 connection");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
218
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
219 c->log->action = "processing HTTP/2 connection";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
220
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
221 h2mcf = ngx_http_get_module_main_conf(hc->conf_ctx, ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
222
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
223 if (h2mcf->recv_buffer == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
224 h2mcf->recv_buffer = ngx_palloc(ngx_cycle->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
225 h2mcf->recv_buffer_size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
226 if (h2mcf->recv_buffer == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
227 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
228 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
229 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
230 }
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 h2c = ngx_pcalloc(c->pool, sizeof(ngx_http_v2_connection_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
233 if (h2c == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
234 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
235 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
236 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
237
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
238 h2c->connection = c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
239 h2c->http_connection = hc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
240
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
241 h2c->send_window = NGX_HTTP_V2_DEFAULT_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
242 h2c->recv_window = NGX_HTTP_V2_MAX_WINDOW;
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 h2c->init_window = NGX_HTTP_V2_DEFAULT_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
245
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
246 h2c->frame_size = NGX_HTTP_V2_DEFAULT_FRAME_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
247
7100
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7029
diff changeset
248 h2c->table_update = 1;
12cadc4669a7 HTTP/2: signal 0-byte HPACK's dynamic table size.
Piotr Sikora <piotrsikora@google.com>
parents: 7029
diff changeset
249
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
250 h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
251
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
252 h2c->concurrent_pushes = h2scf->concurrent_pushes;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
253
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
254 h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
255 if (h2c->pool == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
256 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
257 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
258 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
259
6374
f598de1bfcd4 HTTP/2: fixed excessive memory allocation for pool cleanup.
Valentin Bartenev <vbart@nginx.com>
parents: 6312
diff changeset
260 cln = ngx_pool_cleanup_add(c->pool, 0);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
261 if (cln == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
262 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
263 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
264 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
265
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
266 cln->handler = ngx_http_v2_pool_cleanup;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
267 cln->data = h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
268
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
269 h2c->streams_index = ngx_pcalloc(c->pool, ngx_http_v2_index_size(h2scf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
270 * sizeof(ngx_http_v2_node_t *));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
271 if (h2c->streams_index == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
272 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
273 return;
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
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
276 if (ngx_http_v2_send_settings(h2c) == NGX_ERROR) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
277 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
278 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
279 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
280
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
281 if (ngx_http_v2_send_window_update(h2c, 0, NGX_HTTP_V2_MAX_WINDOW
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
282 - NGX_HTTP_V2_DEFAULT_WINDOW)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
283 == NGX_ERROR)
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 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
286 return;
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 h2c->state.handler = hc->proxy_protocol ? ngx_http_v2_state_proxy_protocol
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
290 : ngx_http_v2_state_preface;
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 ngx_queue_init(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
293 ngx_queue_init(&h2c->dependencies);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
294 ngx_queue_init(&h2c->closed);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
295
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
296 c->data = h2c;
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 rev->handler = ngx_http_v2_read_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
299 c->write->handler = ngx_http_v2_write_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
300
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
301 c->idle = 1;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
302
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
303 ngx_http_v2_read_handler(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
304 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
305
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
306
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
307 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
308 ngx_http_v2_read_handler(ngx_event_t *rev)
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 u_char *p, *end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
311 size_t available;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
312 ssize_t n;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
313 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
314 ngx_http_v2_main_conf_t *h2mcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
315 ngx_http_v2_connection_t *h2c;
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 c = rev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
318 h2c = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
319
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
320 if (rev->timedout) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
321 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
322 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
323 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
324 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
325
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
326 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 read handler");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
327
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
328 h2c->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
329
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
330 if (c->close) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
331 c->close = 0;
6783
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
332
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
333 if (!h2c->goaway) {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
334 h2c->goaway = 1;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
335
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
336 if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR)
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
337 == NGX_ERROR)
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
338 {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
339 ngx_http_v2_finalize_connection(h2c, 0);
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
340 return;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
341 }
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
342
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
343 if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
344 ngx_http_v2_finalize_connection(h2c, 0);
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
345 return;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
346 }
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
347 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
348
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
349 h2c->blocked = 0;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
350
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
351 return;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
352 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
353
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
354 h2mcf = ngx_http_get_module_main_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
355 ngx_http_v2_module);
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 available = h2mcf->recv_buffer_size - 2 * NGX_HTTP_V2_STATE_BUFFER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
358
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
359 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
360 p = h2mcf->recv_buffer;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
361
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
362 ngx_memcpy(p, h2c->state.buffer, NGX_HTTP_V2_STATE_BUFFER_SIZE);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
363 end = p + h2c->state.buffer_used;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
364
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
365 n = c->recv(c, end, available);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
366
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
367 if (n == NGX_AGAIN) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
368 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
369 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
370
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
371 if (n == 0
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
372 && (h2c->state.incomplete || h2c->processing || h2c->pushing))
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
373 {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
374 ngx_log_error(NGX_LOG_INFO, c->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
375 "client prematurely closed connection");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
376 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
377
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
378 if (n == 0 || n == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
379 c->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
380 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
381 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
382 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
383
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
384 end += n;
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 h2c->state.buffer_used = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
387 h2c->state.incomplete = 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 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
390 p = h2c->state.handler(h2c, p, end);
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 if (p == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
393 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
394 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
395
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
396 } while (p != end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
397
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
398 } while (rev->ready);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
399
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
400 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
401 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
402 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
403 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
404
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
405 if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
406 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
407 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
408 }
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 h2c->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
411
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
412 if (h2c->processing || h2c->pushing) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
413 if (rev->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
414 ngx_del_timer(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
415 }
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 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
418 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
419
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
420 ngx_http_v2_handle_connection(h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
421 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
422
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 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
425 ngx_http_v2_write_handler(ngx_event_t *wev)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
426 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
427 ngx_int_t rc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
428 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
429 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
430
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
431 c = wev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
432 h2c = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
433
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
434 if (wev->timedout) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
435 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
436 "http2 write event timed out");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
437 c->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
438 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
439 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
440 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
441
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
442 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 write handler");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
443
6639
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
444 if (h2c->last_out == NULL && !c->buffered) {
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
445
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
446 if (wev->timer_set) {
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
447 ngx_del_timer(wev);
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
448 }
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
449
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
450 ngx_http_v2_handle_connection(h2c);
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
451 return;
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
452 }
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
453
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
454 h2c->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
455
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
456 rc = ngx_http_v2_send_output_queue(h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
457
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
458 if (rc == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
459 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
460 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
461 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
462
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
463 h2c->blocked = 0;
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 if (rc == NGX_AGAIN) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
466 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
467 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
468
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
469 ngx_http_v2_handle_connection(h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
470 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
471
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
472
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
473 ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
474 ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
475 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
476 int tcp_nodelay;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
477 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
478 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
479 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
480 ngx_http_v2_out_frame_t *out, *frame, *fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
481 ngx_http_core_loc_conf_t *clcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
482
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
483 c = h2c->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
484
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
485 if (c->error) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
486 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
487 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
488
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
489 wev = c->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
490
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
491 if (!wev->ready) {
6641
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
492 return NGX_AGAIN;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
493 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
494
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
495 cl = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
496 out = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
497
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
498 for (frame = h2c->last_out; frame; frame = fn) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
499 frame->last->next = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
500 cl = frame->first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
501
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
502 fn = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
503 frame->next = out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
504 out = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
505
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
506 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
507 "http2 frame out: %p sid:%ui bl:%d len:%uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
508 out, out->stream ? out->stream->node->id : 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
509 out->blocked, out->length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
510 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
511
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
512 cl = c->send_chain(c, cl, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
513
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
514 if (cl == NGX_CHAIN_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
515 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
516 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
517
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
518 clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
519 ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
520
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
521 if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
522 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
523 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
524
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
525 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
526 if (ngx_tcp_push(c->fd) == -1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
527 ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
528 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
529 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
530
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
531 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
532 tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
533
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
534 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
535 tcp_nodelay = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
536 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
537
7007
ed1101bbf19f Introduced ngx_tcp_nodelay().
Ruslan Ermilov <ru@nginx.com>
parents: 6989
diff changeset
538 if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
ed1101bbf19f Introduced ngx_tcp_nodelay().
Ruslan Ermilov <ru@nginx.com>
parents: 6989
diff changeset
539 goto error;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
540 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
541
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
542 for ( /* void */ ; out; out = fn) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
543 fn = out->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
544
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
545 if (out->handler(h2c, out) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
546 out->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
547 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
548 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
549
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
550 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
551 "http2 frame sent: %p sid:%ui bl:%d len:%uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
552 out, out->stream ? out->stream->node->id : 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
553 out->blocked, out->length);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
556 frame = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
557
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
558 for ( /* void */ ; out; out = fn) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
559 fn = out->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
560 out->next = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
561 frame = out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
562 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
563
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
564 h2c->last_out = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
565
6641
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
566 if (!wev->ready) {
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
567 ngx_add_timer(wev, clcf->send_timeout);
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
568 return NGX_AGAIN;
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
569 }
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
570
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
571 if (wev->timer_set) {
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
572 ngx_del_timer(wev);
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
573 }
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
574
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
575 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
576
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
577 error:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
578
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
579 c->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
580
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
581 if (!h2c->blocked) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
582 ngx_post_event(wev, &ngx_posted_events);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
583 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
584
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
585 return NGX_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
589 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
590 ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
591 {
6642
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
592 ngx_int_t rc;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
593 ngx_connection_t *c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
594 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
595
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
596 if (h2c->last_out || h2c->processing || h2c->pushing) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
597 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
598 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
599
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
600 c = h2c->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
601
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
602 if (c->error) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
603 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
604 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
605 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
606
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
607 if (c->buffered) {
6642
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
608 h2c->blocked = 1;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
609
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
610 rc = ngx_http_v2_send_output_queue(h2c);
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
611
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
612 h2c->blocked = 0;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
613
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
614 if (rc == NGX_ERROR) {
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
615 ngx_http_close_connection(c);
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
616 return;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
617 }
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
618
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
619 if (rc == NGX_AGAIN) {
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
620 return;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
621 }
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
622
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
623 /* rc == NGX_OK */
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
624 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
625
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
626 if (h2c->goaway) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
627 ngx_http_close_connection(c);
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
628 return;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
629 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
630
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
631 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
632 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
633 if (h2c->state.incomplete) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
634 ngx_add_timer(c->read, h2scf->recv_timeout);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
635 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
636 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
637
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
638 ngx_destroy_pool(h2c->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
639
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
640 h2c->pool = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
641 h2c->free_frames = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
642 h2c->free_fake_connections = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
643
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
644 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
645 if (c->ssl) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
646 ngx_ssl_free_buffer(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
647 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
648 #endif
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 c->destroyed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
651 ngx_reusable_connection(c, 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
652
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
653 c->write->handler = ngx_http_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
654 c->read->handler = ngx_http_v2_idle_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
655
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
656 if (c->write->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
657 ngx_del_timer(c->write);
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 ngx_add_timer(c->read, h2scf->idle_timeout);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
661 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
662
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
663
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
664 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
665 ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
666 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
667 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
668 ngx_log_t *log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
669
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
670 log = h2c->connection->log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
671 log->action = "reading PROXY protocol";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
672
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
673 pos = ngx_proxy_protocol_read(h2c->connection, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
674
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
675 log->action = "processing HTTP/2 connection";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
676
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
677 if (pos == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
678 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
679 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
680
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
681 return ngx_http_v2_state_preface(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
682 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
683
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
684
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
685 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
686 ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
687 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
688 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
689 static const u_char preface[] = "PRI * HTTP/2.0\r\n";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
690
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
691 if ((size_t) (end - pos) < sizeof(preface) - 1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
692 return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_preface);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
693 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
694
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
695 if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
696 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
697 "invalid http2 connection preface \"%*s\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
698 sizeof(preface) - 1, pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
699
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
700 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
701 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
702
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
703 return ngx_http_v2_state_preface_end(h2c, pos + sizeof(preface) - 1, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
704 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
705
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
706
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
707 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
708 ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
709 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
710 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
711 static const u_char preface[] = "\r\nSM\r\n\r\n";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
712
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
713 if ((size_t) (end - pos) < sizeof(preface) - 1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
714 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
715 ngx_http_v2_state_preface_end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
716 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
717
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
718 if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
719 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
720 "invalid http2 connection preface \"%*s\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
721 sizeof(preface) - 1, pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
722
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
723 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
724 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
725
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
726 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
727 "http2 preface verified");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
728
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
729 return ngx_http_v2_state_head(h2c, pos + sizeof(preface) - 1, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
730 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
731
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
732
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
733 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
734 ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
735 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
736 uint32_t head;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
737 ngx_uint_t type;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
738
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
739 if (end - pos < NGX_HTTP_V2_FRAME_HEADER_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
740 return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_head);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
741 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
742
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
743 head = ngx_http_v2_parse_uint32(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
744
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
745 h2c->state.length = ngx_http_v2_parse_length(head);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
746 h2c->state.flags = pos[4];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
747
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
748 h2c->state.sid = ngx_http_v2_parse_sid(&pos[5]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
749
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
750 pos += NGX_HTTP_V2_FRAME_HEADER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
751
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
752 type = ngx_http_v2_parse_type(head);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
753
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
754 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
7108
2bf605c6edf7 HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7106
diff changeset
755 "http2 frame type:%ui f:%Xd l:%uz sid:%ui",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
756 type, h2c->state.flags, h2c->state.length, h2c->state.sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
757
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
758 if (type >= NGX_HTTP_V2_FRAME_STATES) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
759 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
760 "http2 frame with unknown type %ui", type);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
761 return ngx_http_v2_state_skip(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
762 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
763
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
764 return ngx_http_v2_frame_states[type](h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
765 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
766
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
767
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
768 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
769 ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
770 {
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
771 size_t size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
772 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
773 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
774
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
775 size = h2c->state.length;
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
776
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
777 if (h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
778
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
779 if (h2c->state.length == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
780 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
781 "client sent padded DATA frame "
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
782 "with incorrect length: 0");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
783
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
784 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
785 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
786
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
787 if (end - pos == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
788 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
789 ngx_http_v2_state_data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
790 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
791
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
792 h2c->state.padding = *pos++;
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
793
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
794 if (h2c->state.padding >= size) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
795 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
796 "client sent padded DATA frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
797 "with incorrect length: %uz, padding: %uz",
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
798 size, h2c->state.padding);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
799
6955
d38161da62cd HTTP/2: emit PROTOCOL_ERROR on padding errors.
Piotr Sikora <piotrsikora@google.com>
parents: 6954
diff changeset
800 return ngx_http_v2_connection_error(h2c,
d38161da62cd HTTP/2: emit PROTOCOL_ERROR on padding errors.
Piotr Sikora <piotrsikora@google.com>
parents: 6954
diff changeset
801 NGX_HTTP_V2_PROTOCOL_ERROR);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
802 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
803
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
804 h2c->state.length -= 1 + h2c->state.padding;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
805 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
806
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
807 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
808 "http2 DATA frame");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
809
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
810 if (size > h2c->recv_window) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
811 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
812 "client violated connection flow control: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
813 "received DATA frame length %uz, available window %uz",
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
814 size, h2c->recv_window);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
815
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
816 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
817 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
818
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
819 h2c->recv_window -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
820
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
821 if (h2c->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
822
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
823 if (ngx_http_v2_send_window_update(h2c, 0, NGX_HTTP_V2_MAX_WINDOW
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
824 - h2c->recv_window)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
825 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
826 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
827 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
828 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
829 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
830
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
831 h2c->recv_window = NGX_HTTP_V2_MAX_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
832 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
833
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
834 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
835
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
836 if (node == NULL || node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
837 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
838 "unknown http2 stream");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
839
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
840 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
841 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
842
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
843 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
844
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
845 if (size > stream->recv_window) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
846 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
847 "client violated flow control for stream %ui: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
848 "received DATA frame length %uz, available window %uz",
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
849 node->id, size, stream->recv_window);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
850
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
851 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
852 NGX_HTTP_V2_FLOW_CTRL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
853 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
854 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
855 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
856 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
857 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
858
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
859 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
860 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
861
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
862 stream->recv_window -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
863
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
864 if (stream->no_flow_control
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
865 && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
866 {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
867 if (ngx_http_v2_send_window_update(h2c, node->id,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
868 NGX_HTTP_V2_MAX_WINDOW
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
869 - stream->recv_window)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
870 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
871 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
872 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
873 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
874 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
875
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
876 stream->recv_window = NGX_HTTP_V2_MAX_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
877 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
878
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
879 if (stream->in_closed) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
880 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
881 "client sent DATA frame for half-closed stream %ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
882 node->id);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
883
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
884 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
885 NGX_HTTP_V2_STREAM_CLOSED)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
886 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
887 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
888 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
889 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
890 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
891
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
892 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
893 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
894
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
895 h2c->state.stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
896
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
897 return ngx_http_v2_state_read_data(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
898 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
899
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
900
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
901 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
902 ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
903 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
904 {
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
905 size_t size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
906 ngx_buf_t *buf;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
907 ngx_int_t rc;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
908 ngx_http_request_t *r;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
909 ngx_http_v2_stream_t *stream;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
910 ngx_http_v2_srv_conf_t *h2scf;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
911
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
912 stream = h2c->state.stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
913
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
914 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
915 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
916 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
917
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
918 if (stream->skip_data) {
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
919 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
920 "skipping http2 DATA frame");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
921
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
922 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
923 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
924
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
925 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
926
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
927 if (size >= h2c->state.length) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
928 size = h2c->state.length;
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
929 stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
930 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
931
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
932 r = stream->request;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
933
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
934 if (r->request_body) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
935 rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
936
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
937 if (rc != NGX_OK) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
938 stream->skip_data = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
939 ngx_http_finalize_request(r, rc);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
940 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
941
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
942 } else if (size) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
943 buf = stream->preread;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
944
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
945 if (buf == NULL) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
946 h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
947
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
948 buf = ngx_create_temp_buf(r->pool, h2scf->preread_size);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
949 if (buf == NULL) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
950 return ngx_http_v2_connection_error(h2c,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
951 NGX_HTTP_V2_INTERNAL_ERROR);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
952 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
953
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
954 stream->preread = buf;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
955 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
956
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
957 if (size > (size_t) (buf->end - buf->last)) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
958 ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
959 "http2 preread buffer overflow");
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
960 return ngx_http_v2_connection_error(h2c,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
961 NGX_HTTP_V2_INTERNAL_ERROR);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
962 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
963
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
964 buf->last = ngx_cpymem(buf->last, pos, size);
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
965 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
966
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
967 pos += size;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
968 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
969
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
970 if (h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
971 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
972 ngx_http_v2_state_read_data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
973 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
974
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
975 if (h2c->state.padding) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
976 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
977 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
978
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
979 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
980 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
981
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
982
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
983 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
984 ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
985 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
986 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
987 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
988 ngx_uint_t padded, priority, depend, dependency, excl, weight;
6513
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
989 ngx_uint_t status;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
990 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
991 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
992 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
993
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
994 padded = h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
995 priority = h2c->state.flags & NGX_HTTP_V2_PRIORITY_FLAG;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
996
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
997 size = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
998
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
999 if (padded) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1000 size++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1001 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1002
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1003 if (priority) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1004 size += sizeof(uint32_t) + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1005 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1006
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1007 if (h2c->state.length < size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1008 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1009 "client sent HEADERS frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1010 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1011
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1012 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1013 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1014
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1015 if (h2c->state.length == size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1016 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1017 "client sent HEADERS frame with empty header block");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1018
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1019 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1020 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1021
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1022 if (h2c->goaway) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1023 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1024 "skipping http2 HEADERS frame");
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1025 return ngx_http_v2_state_skip(h2c, pos, end);
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1026 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1027
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1028 if ((size_t) (end - pos) < size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1029 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1030 ngx_http_v2_state_headers);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1031 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1032
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1033 h2c->state.length -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1034
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1035 if (padded) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1036 h2c->state.padding = *pos++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1037
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1038 if (h2c->state.padding > h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1039 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1040 "client sent padded HEADERS frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1041 "with incorrect length: %uz, padding: %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1042 h2c->state.length, h2c->state.padding);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1043
6955
d38161da62cd HTTP/2: emit PROTOCOL_ERROR on padding errors.
Piotr Sikora <piotrsikora@google.com>
parents: 6954
diff changeset
1044 return ngx_http_v2_connection_error(h2c,
d38161da62cd HTTP/2: emit PROTOCOL_ERROR on padding errors.
Piotr Sikora <piotrsikora@google.com>
parents: 6954
diff changeset
1045 NGX_HTTP_V2_PROTOCOL_ERROR);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1046 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1047
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1048 h2c->state.length -= h2c->state.padding;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1049 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1050
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1051 depend = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1052 excl = 0;
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1053 weight = NGX_HTTP_V2_DEFAULT_WEIGHT;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1054
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1055 if (priority) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1056 dependency = ngx_http_v2_parse_uint32(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1057
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1058 depend = dependency & 0x7fffffff;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1059 excl = dependency >> 31;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1060 weight = pos[4] + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1061
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1062 pos += sizeof(uint32_t) + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1063 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1064
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1065 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1066 "http2 HEADERS frame sid:%ui "
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1067 "depends on %ui excl:%ui weight:%ui",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1068 h2c->state.sid, depend, excl, weight);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1069
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1070 if (h2c->state.sid % 2 == 0 || h2c->state.sid <= h2c->last_sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1071 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1072 "client sent HEADERS frame with incorrect identifier "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1073 "%ui, the last was %ui", h2c->state.sid, h2c->last_sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1074
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1075 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1076 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1077
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1078 h2c->last_sid = h2c->state.sid;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1079
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1080 h2c->state.pool = ngx_create_pool(1024, h2c->connection->log);
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1081 if (h2c->state.pool == NULL) {
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1082 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1083 }
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1084
6271
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1085 if (depend == h2c->state.sid) {
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1086 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1087 "client sent HEADERS frame for stream %ui "
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1088 "with incorrect dependency", h2c->state.sid);
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1089
6513
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1090 status = NGX_HTTP_V2_PROTOCOL_ERROR;
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1091 goto rst_stream;
6271
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1092 }
22ee99422329 HTTP/2: reject self-dependent streams.
Piotr Sikora <piotrsikora@google.com>
parents: 6268
diff changeset
1093
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1094 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1095 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1096
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1097 h2c->state.header_limit = h2scf->max_header_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1098
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1099 if (h2c->processing >= h2scf->concurrent_streams) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1100 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1101 "concurrent streams exceeded %ui", h2c->processing);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1102
6513
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1103 status = NGX_HTTP_V2_REFUSED_STREAM;
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1104 goto rst_stream;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1105 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1106
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1107 if (!h2c->settings_ack
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1108 && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1109 && h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW)
6514
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1110 {
6516
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1111 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1112 "client sent stream with data "
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1113 "before settings were acknowledged");
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1114
6514
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1115 status = NGX_HTTP_V2_REFUSED_STREAM;
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1116 goto rst_stream;
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1117 }
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1118
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1119 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1120
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1121 if (node == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1122 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1123 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1124
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1125 if (node->parent) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1126 ngx_queue_remove(&node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1127 h2c->closed_nodes--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1128 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1129
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1130 stream = ngx_http_v2_create_stream(h2c, 0);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1131 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1132 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1133 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1134
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1135 h2c->state.stream = stream;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1136
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1137 stream->pool = h2c->state.pool;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1138 h2c->state.keep_pool = 1;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1139
6375
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1140 stream->request->request_length = h2c->state.length;
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1141
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1142 stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1143 stream->node = node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1144
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1145 node->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1146
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1147 if (priority || node->parent == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1148 node->weight = weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1149 ngx_http_v2_set_dependency(h2c, node, depend, excl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1150 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1151
6783
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1152 if (h2c->connection->requests >= h2scf->max_requests) {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1153 h2c->goaway = 1;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1154
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1155 if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1156 return ngx_http_v2_connection_error(h2c,
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1157 NGX_HTTP_V2_INTERNAL_ERROR);
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1158 }
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1159 }
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1160
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1161 return ngx_http_v2_state_header_block(h2c, pos, end);
6513
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1162
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1163 rst_stream:
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1164
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1165 if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) {
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1166 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1167 }
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1168
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1169 return ngx_http_v2_state_header_block(h2c, pos, end);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1170 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1171
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1172
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1173 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1174 ngx_http_v2_state_header_block(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1175 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1176 {
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1177 u_char ch;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1178 ngx_int_t value;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1179 ngx_uint_t indexed, size_update, prefix;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1180
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1181 if (end - pos < 1) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1182 return ngx_http_v2_state_headers_save(h2c, pos, end,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1183 ngx_http_v2_state_header_block);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1184 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1185
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1186 if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1187 && h2c->state.length < NGX_HTTP_V2_INT_OCTETS)
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1188 {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1189 return ngx_http_v2_handle_continuation(h2c, pos, end,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1190 ngx_http_v2_state_header_block);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1191 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1192
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1193 size_update = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1194 indexed = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1195
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1196 ch = *pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1197
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1198 if (ch >= (1 << 7)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1199 /* indexed header field */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1200 indexed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1201 prefix = ngx_http_v2_prefix(7);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1202
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1203 } else if (ch >= (1 << 6)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1204 /* literal header field with incremental indexing */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1205 h2c->state.index = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1206 prefix = ngx_http_v2_prefix(6);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1207
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1208 } else if (ch >= (1 << 5)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1209 /* dynamic table size update */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1210 size_update = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1211 prefix = ngx_http_v2_prefix(5);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1212
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1213 } else if (ch >= (1 << 4)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1214 /* literal header field never indexed */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1215 prefix = ngx_http_v2_prefix(4);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1216
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1217 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1218 /* literal header field without indexing */
6260
0e37389c0bd5 HTTP/2: fixed parsing of literal header fields without indexing.
Valentin Bartenev <vbart@nginx.com>
parents: 6256
diff changeset
1219 prefix = ngx_http_v2_prefix(4);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1220 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1221
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1222 value = ngx_http_v2_parse_int(h2c, &pos, end, prefix);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1223
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1224 if (value < 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1225 if (value == NGX_AGAIN) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1226 return ngx_http_v2_state_headers_save(h2c, pos, end,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1227 ngx_http_v2_state_header_block);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1228 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1229
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1230 if (value == NGX_DECLINED) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1231 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1232 "client sent header block with too long %s value",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1233 size_update ? "size update" : "header index");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1234
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1235 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1236 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1237
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1238 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1239 "client sent header block with incorrect length");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1240
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1241 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1242 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1243
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1244 if (indexed) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1245 if (ngx_http_v2_get_indexed_header(h2c, value, 0) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1246 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1247 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1248
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1249 return ngx_http_v2_state_process_header(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1250 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1251
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1252 if (size_update) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1253 if (ngx_http_v2_table_size(h2c, value) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1254 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1255 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1256
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1257 return ngx_http_v2_state_header_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1258 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1259
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1260 if (value == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1261 h2c->state.parse_name = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1262
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1263 } else if (ngx_http_v2_get_indexed_header(h2c, value, 1) != NGX_OK) {
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1264 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1265 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1266
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1267 h2c->state.parse_value = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1268
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1269 return ngx_http_v2_state_field_len(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1270 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1271
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1272
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1273 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1274 ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1275 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1276 {
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1277 size_t alloc;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1278 ngx_int_t len;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1279 ngx_uint_t huff;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1280 ngx_http_v2_srv_conf_t *h2scf;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1281
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1282 if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1283 && h2c->state.length < NGX_HTTP_V2_INT_OCTETS)
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1284 {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1285 return ngx_http_v2_handle_continuation(h2c, pos, end,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1286 ngx_http_v2_state_field_len);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1287 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1288
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1289 if (h2c->state.length < 1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1290 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1291 "client sent header block with incorrect length");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1292
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1293 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1294 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1295
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1296 if (end - pos < 1) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1297 return ngx_http_v2_state_headers_save(h2c, pos, end,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1298 ngx_http_v2_state_field_len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1299 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1300
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1301 huff = *pos >> 7;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1302 len = ngx_http_v2_parse_int(h2c, &pos, end, ngx_http_v2_prefix(7));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1303
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1304 if (len < 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1305 if (len == NGX_AGAIN) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1306 return ngx_http_v2_state_headers_save(h2c, pos, end,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1307 ngx_http_v2_state_field_len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1308 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1309
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1310 if (len == NGX_DECLINED) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1311 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1312 "client sent header field with too long length value");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1313
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1314 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1315 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1316
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1317 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1318 "client sent header block with incorrect length");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1319
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1320 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1321 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1322
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1323 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
7108
2bf605c6edf7 HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7106
diff changeset
1324 "http2 %s string, len:%i",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1325 huff ? "encoded" : "raw", len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1326
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1327 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1328 ngx_http_v2_module);
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1329
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1330 if ((size_t) len > h2scf->max_field_size) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1331 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1332 "client exceeded http2_max_field_size limit");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1333
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1334 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1335 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1336
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1337 h2c->state.field_rest = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1338
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1339 if (h2c->state.stream == NULL && !h2c->state.index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1340 return ngx_http_v2_state_field_skip(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1341 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1342
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1343 alloc = (huff ? len * 8 / 5 : len) + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1344
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1345 h2c->state.field_start = ngx_pnalloc(h2c->state.pool, alloc);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1346 if (h2c->state.field_start == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1347 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1348 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1349
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1350 h2c->state.field_end = h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1351
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1352 if (huff) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1353 return ngx_http_v2_state_field_huff(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1354 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1355
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1356 return ngx_http_v2_state_field_raw(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1357 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1358
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1359
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1360 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1361 ngx_http_v2_state_field_huff(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1362 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1363 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1364 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1365
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1366 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1367
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1368 if (size > h2c->state.field_rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1369 size = h2c->state.field_rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1370 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1371
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1372 if (size > h2c->state.length) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1373 size = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1374 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1375
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1376 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1377 h2c->state.field_rest -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1378
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1379 if (ngx_http_v2_huff_decode(&h2c->state.field_state, pos, size,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1380 &h2c->state.field_end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1381 h2c->state.field_rest == 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1382 h2c->connection->log)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1383 != NGX_OK)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1384 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1385 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1386 "client sent invalid encoded header field");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1387
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1388 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1389 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1390
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1391 pos += size;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1392
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1393 if (h2c->state.field_rest == 0) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1394 *h2c->state.field_end = '\0';
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1395 return ngx_http_v2_state_process_header(h2c, pos, end);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1396 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1397
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1398 if (h2c->state.length) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1399 return ngx_http_v2_state_headers_save(h2c, pos, end,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1400 ngx_http_v2_state_field_huff);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1401 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1402
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1403 if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1404 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1405 "client sent header field with incorrect length");
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1406
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1407 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1408 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1409
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1410 return ngx_http_v2_handle_continuation(h2c, pos, end,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1411 ngx_http_v2_state_field_huff);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1412 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1415 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1416 ngx_http_v2_state_field_raw(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1417 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1418 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1419 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1420
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1421 size = end - pos;
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 if (size > h2c->state.field_rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1424 size = h2c->state.field_rest;
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
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1427 if (size > h2c->state.length) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1428 size = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1429 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1430
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1431 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1432 h2c->state.field_rest -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1433
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1434 h2c->state.field_end = ngx_cpymem(h2c->state.field_end, pos, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1435
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1436 pos += size;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1437
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1438 if (h2c->state.field_rest == 0) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1439 *h2c->state.field_end = '\0';
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1440 return ngx_http_v2_state_process_header(h2c, pos, end);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1441 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1442
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1443 if (h2c->state.length) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1444 return ngx_http_v2_state_headers_save(h2c, pos, end,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1445 ngx_http_v2_state_field_raw);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1446 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1447
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1448 if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1449 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1450 "client sent header field with incorrect length");
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1451
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1452 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1453 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1454
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1455 return ngx_http_v2_handle_continuation(h2c, pos, end,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1456 ngx_http_v2_state_field_raw);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1457 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1458
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1459
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1460 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1461 ngx_http_v2_state_field_skip(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1462 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1463 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1464 size_t size;
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 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1467
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1468 if (size > h2c->state.field_rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1469 size = h2c->state.field_rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1470 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1471
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1472 if (size > h2c->state.length) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1473 size = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1474 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1475
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1476 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1477 h2c->state.field_rest -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1478
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1479 pos += size;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1480
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1481 if (h2c->state.field_rest == 0) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1482 return ngx_http_v2_state_process_header(h2c, pos, end);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1483 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1484
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1485 if (h2c->state.length) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1486 return ngx_http_v2_state_save(h2c, pos, end,
6248
f5380c244cd7 HTTP/2: fixed HPACK header field parsing.
Valentin Bartenev <vbart@nginx.com>
parents: 6246
diff changeset
1487 ngx_http_v2_state_field_skip);
f5380c244cd7 HTTP/2: fixed HPACK header field parsing.
Valentin Bartenev <vbart@nginx.com>
parents: 6246
diff changeset
1488 }
f5380c244cd7 HTTP/2: fixed HPACK header field parsing.
Valentin Bartenev <vbart@nginx.com>
parents: 6246
diff changeset
1489
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1490 if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1491 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1492 "client sent header field with incorrect length");
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1493
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1494 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1495 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1496
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1497 return ngx_http_v2_handle_continuation(h2c, pos, end,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1498 ngx_http_v2_state_field_skip);
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1501
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1502 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1503 ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1504 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1505 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1506 size_t len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1507 ngx_int_t rc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1508 ngx_table_elt_t *h;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1509 ngx_http_header_t *hh;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1510 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1511 ngx_http_v2_header_t *header;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1512 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1513 ngx_http_core_main_conf_t *cmcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1514
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1515 static ngx_str_t cookie = ngx_string("cookie");
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 header = &h2c->state.header;
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 if (h2c->state.parse_name) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1520 h2c->state.parse_name = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1521
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1522 header->name.len = h2c->state.field_end - h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1523 header->name.data = h2c->state.field_start;
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 return ngx_http_v2_state_field_len(h2c, pos, end);
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 if (h2c->state.parse_value) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1529 h2c->state.parse_value = 0;
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 header->value.len = h2c->state.field_end - h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1532 header->value.data = h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1533 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1534
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1535 len = header->name.len + header->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1536
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1537 if (len > h2c->state.header_limit) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1538 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1539 "client exceeded http2_max_header_size limit");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1540
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1541 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1544 h2c->state.header_limit -= len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1545
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1546 if (h2c->state.index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1547 if (ngx_http_v2_add_header(h2c, header) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1548 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1549 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1550 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1551
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1552 h2c->state.index = 0;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1555 if (h2c->state.stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1556 return ngx_http_v2_state_header_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1557 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1558
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1559 r = h2c->state.stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1560
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1561 /* TODO Optimization: validate headers while parsing. */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1562 if (ngx_http_v2_validate_header(r, header) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1563 if (ngx_http_v2_terminate_stream(h2c, h2c->state.stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1564 NGX_HTTP_V2_PROTOCOL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1565 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1566 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1567 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1568 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1569 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1570
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1571 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1572 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1573
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1574 if (header->name.data[0] == ':') {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1575 rc = ngx_http_v2_pseudo_header(r, header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1576
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1577 if (rc == NGX_OK) {
7016
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1578 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
7108
2bf605c6edf7 HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7106
diff changeset
1579 "http2 header: \":%V: %V\"",
7016
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1580 &header->name, &header->value);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1581
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1582 return ngx_http_v2_state_header_complete(h2c, pos, end);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1585 if (rc == NGX_ABORT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1586 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1587 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1588
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1589 if (rc == NGX_DECLINED) {
7192
d5a535774861 HTTP/2: finalize request as bad if parsing of pseudo-headers fails.
Ruslan Ermilov <ru@nginx.com>
parents: 7191
diff changeset
1590 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1591 goto error;
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 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1597 if (r->invalid_header) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1598 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
1599
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1600 if (cscf->ignore_invalid_headers) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1601 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1602 "client sent invalid header: \"%V\"", &header->name);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1603
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1604 return ngx_http_v2_state_header_complete(h2c, pos, end);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1608 if (header->name.len == cookie.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1609 && ngx_memcmp(header->name.data, cookie.data, cookie.len) == 0)
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_cookie(r, header) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1612 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1613 NGX_HTTP_V2_INTERNAL_ERROR);
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
7016
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1616 } else {
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1617 h = ngx_list_push(&r->headers_in.headers);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1618 if (h == NULL) {
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1619 return ngx_http_v2_connection_error(h2c,
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1620 NGX_HTTP_V2_INTERNAL_ERROR);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1621 }
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1622
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1623 h->key.len = header->name.len;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1624 h->key.data = header->name.data;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1625
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1626 /*
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1627 * TODO Optimization: precalculate hash
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1628 * and handler for indexed headers.
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1629 */
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1630 h->hash = ngx_hash_key(h->key.data, h->key.len);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1631
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1632 h->value.len = header->value.len;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1633 h->value.data = header->value.data;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1634
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1635 h->lowcase_key = h->key.data;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1636
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1637 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1638
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1639 hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1640 h->lowcase_key, h->key.len);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1641
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1642 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1643 goto error;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1644 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1645 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1646
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1647 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
7108
2bf605c6edf7 HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7106
diff changeset
1648 "http2 header: \"%V: %V\"",
7016
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1649 &header->name, &header->value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1650
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1651 return ngx_http_v2_state_header_complete(h2c, pos, end);
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 error:
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 h2c->state.stream = NULL;
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 return ngx_http_v2_state_header_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1658 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1659
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1660
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1661 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1662 ngx_http_v2_state_header_complete(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1663 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1664 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1665 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1666
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1667 if (h2c->state.length) {
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1668 h2c->state.handler = ngx_http_v2_state_header_block;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1669 return pos;
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
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1672 if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1673 return ngx_http_v2_handle_continuation(h2c, pos, end,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1674 ngx_http_v2_state_header_complete);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1675 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1676
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1677 stream = h2c->state.stream;
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 if (stream) {
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1680 ngx_http_v2_run_request(stream->request);
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1681 }
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1682
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1683 if (!h2c->state.keep_pool) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1684 ngx_destroy_pool(h2c->state.pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1685 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1686
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1687 h2c->state.pool = NULL;
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1688 h2c->state.keep_pool = 0;
6246
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 if (h2c->state.padding) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1691 return ngx_http_v2_state_skip_padded(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1692 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1693
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1694 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1695 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1696
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1697
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1698 static u_char *
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1699 ngx_http_v2_handle_continuation(ngx_http_v2_connection_t *h2c, u_char *pos,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1700 u_char *end, ngx_http_v2_handler_pt handler)
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1701 {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1702 u_char *p;
6376
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1703 size_t len, skip;
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1704 uint32_t head;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1705
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1706 len = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1707
6376
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1708 if (h2c->state.padding && (size_t) (end - pos) > len) {
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1709 skip = ngx_min(h2c->state.padding, (end - pos) - len);
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1710
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1711 h2c->state.padding -= skip;
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1712
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1713 p = pos;
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1714 pos += skip;
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1715 ngx_memmove(pos, p, len);
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1716 }
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1717
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1718 if ((size_t) (end - pos) < len + NGX_HTTP_V2_FRAME_HEADER_SIZE) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1719 return ngx_http_v2_state_headers_save(h2c, pos, end, handler);
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1720 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1721
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1722 p = pos + len;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1723
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1724 head = ngx_http_v2_parse_uint32(p);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1725
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1726 if (ngx_http_v2_parse_type(head) != NGX_HTTP_V2_CONTINUATION_FRAME) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1727 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1728 "client sent inappropriate frame while CONTINUATION was expected");
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1729
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1730 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1731 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1732
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1733 h2c->state.flags |= p[4];
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1734
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1735 if (h2c->state.sid != ngx_http_v2_parse_sid(&p[5])) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1736 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1737 "client sent CONTINUATION frame with incorrect identifier");
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1738
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1739 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1740 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1741
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1742 p = pos;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1743 pos += NGX_HTTP_V2_FRAME_HEADER_SIZE;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1744
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1745 ngx_memcpy(pos, p, len);
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1746
6375
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1747 len = ngx_http_v2_parse_length(head);
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1748
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1749 h2c->state.length += len;
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1750
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1751 if (h2c->state.stream) {
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1752 h2c->state.stream->request->request_length += len;
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1753 }
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1754
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1755 h2c->state.handler = handler;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1756 return pos;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1757 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1758
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1759
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1760 static u_char *
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1761 ngx_http_v2_state_priority(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1762 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1763 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1764 ngx_uint_t depend, dependency, excl, weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1765 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1766
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1767 if (h2c->state.length != NGX_HTTP_V2_PRIORITY_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1768 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1769 "client sent PRIORITY frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1770 h2c->state.length);
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 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1773 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1774
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1775 if (end - pos < NGX_HTTP_V2_PRIORITY_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1776 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1777 ngx_http_v2_state_priority);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1778 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1779
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1780 dependency = ngx_http_v2_parse_uint32(pos);
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 depend = dependency & 0x7fffffff;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1783 excl = dependency >> 31;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1784 weight = pos[4] + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1785
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1786 pos += NGX_HTTP_V2_PRIORITY_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1787
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1788 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1789 "http2 PRIORITY frame sid:%ui "
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1790 "depends on %ui excl:%ui weight:%ui",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1791 h2c->state.sid, depend, excl, weight);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1792
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1793 if (h2c->state.sid == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1794 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1795 "client sent PRIORITY frame with incorrect identifier");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1796
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1797 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1798 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1799
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1800 if (depend == h2c->state.sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1801 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1802 "client sent PRIORITY frame for stream %ui "
6284
66ee1c5cb6aa HTTP/2: fixed spelling.
Valentin Bartenev <vbart@nginx.com>
parents: 6280
diff changeset
1803 "with incorrect dependency", h2c->state.sid);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1804
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1805 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1806
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1807 if (node && node->stream) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1808 if (ngx_http_v2_terminate_stream(h2c, node->stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1809 NGX_HTTP_V2_PROTOCOL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1810 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1811 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1812 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1813 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1814 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1815
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1816 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1817 if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1818 NGX_HTTP_V2_PROTOCOL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1819 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1820 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1821 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1822 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1823 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1824 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1825
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1826 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1827 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1828
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1829 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1830
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1831 if (node == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1832 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1833 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1834
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1835 node->weight = weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1836
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1837 if (node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1838 if (node->parent == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1839 h2c->closed_nodes++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1840
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1841 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1842 ngx_queue_remove(&node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1843 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1844
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1845 ngx_queue_insert_tail(&h2c->closed, &node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1846 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1847
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1848 ngx_http_v2_set_dependency(h2c, node, depend, excl);
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 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1851 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1852
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1853
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1854 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1855 ngx_http_v2_state_rst_stream(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1856 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1857 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1858 ngx_uint_t status;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1859 ngx_event_t *ev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1860 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1861 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1862 ngx_http_v2_stream_t *stream;
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 if (h2c->state.length != NGX_HTTP_V2_RST_STREAM_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1865 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1866 "client sent RST_STREAM frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1867 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1868
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1869 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1870 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1871
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1872 if (end - pos < NGX_HTTP_V2_RST_STREAM_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1873 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1874 ngx_http_v2_state_rst_stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1875 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1876
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1877 status = ngx_http_v2_parse_uint32(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1878
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1879 pos += NGX_HTTP_V2_RST_STREAM_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1880
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1881 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
1882 "http2 RST_STREAM frame, sid:%ui status:%ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1883 h2c->state.sid, status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1884
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1885 if (h2c->state.sid == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1886 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1887 "client sent RST_STREAM frame with incorrect identifier");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1888
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1889 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1890 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1891
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1892 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1893
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1894 if (node == NULL || node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1895 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
1896 "unknown http2 stream");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1897
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1898 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1899 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1900
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1901 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1902
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1903 stream->in_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1904 stream->out_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1905
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1906 fc = stream->request->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1907 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1908
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1909 switch (status) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1910
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1911 case NGX_HTTP_V2_CANCEL:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1912 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1913 "client canceled stream %ui", h2c->state.sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1914 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1915
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1916 case NGX_HTTP_V2_REFUSED_STREAM:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1917 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1918 "client refused stream %ui", h2c->state.sid);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1919 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1920
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1921 case NGX_HTTP_V2_INTERNAL_ERROR:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1922 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1923 "client terminated stream %ui due to internal error",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1924 h2c->state.sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1925 break;
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 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1928 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1929 "client terminated stream %ui with status %ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1930 h2c->state.sid, status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1931 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1932 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1933
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1934 ev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1935 ev->handler(ev);
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_http_v2_state_complete(h2c, pos, end);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1941 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1942 ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1943 u_char *end)
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 (h2c->state.flags == NGX_HTTP_V2_ACK_FLAG) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1946
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1947 if (h2c->state.length != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1948 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1949 "client sent SETTINGS frame with the ACK flag "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1950 "and nonzero length");
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 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1953 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1954
6514
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1955 h2c->settings_ack = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1956
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1957 return ngx_http_v2_state_complete(h2c, pos, end);
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 (h2c->state.length % NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1961 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1962 "client sent SETTINGS frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1963 h2c->state.length);
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 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1968 return ngx_http_v2_state_settings_params(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1969 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1970
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1973 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1974 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1975 {
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
1976 ssize_t window_delta;
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
1977 ngx_uint_t id, value;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1978 ngx_http_v2_srv_conf_t *h2scf;
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
1979 ngx_http_v2_out_frame_t *frame;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1980
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
1981 window_delta = 0;
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
1982
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1983 while (h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1984 if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1985 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1986 ngx_http_v2_state_settings_params);
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 h2c->state.length -= NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1990
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1991 id = ngx_http_v2_parse_uint16(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1992 value = ngx_http_v2_parse_uint32(&pos[2]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1993
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1994 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1995 "http2 setting %ui:%ui", id, value);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1996
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1997 switch (id) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1998
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1999 case NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2000
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2001 if (value > NGX_HTTP_V2_MAX_WINDOW) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2002 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2003 "client sent SETTINGS frame with incorrect "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2004 "INITIAL_WINDOW_SIZE value %ui", value);
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 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2007 NGX_HTTP_V2_FLOW_CTRL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2008 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2009
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2010 window_delta = value - h2c->init_window;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2011 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2012
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2013 case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING:
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
2014
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2015 if (value > NGX_HTTP_V2_MAX_FRAME_SIZE
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2016 || value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE)
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 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2019 "client sent SETTINGS frame with incorrect "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2020 "MAX_FRAME_SIZE value %ui", value);
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 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2023 NGX_HTTP_V2_PROTOCOL_ERROR);
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 h2c->frame_size = value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2027 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2028
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2029 case NGX_HTTP_V2_ENABLE_PUSH_SETTING:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2030
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2031 if (value > 1) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2032 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2033 "client sent SETTINGS frame with incorrect "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2034 "ENABLE_PUSH value %ui", value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2035
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2036 return ngx_http_v2_connection_error(h2c,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2037 NGX_HTTP_V2_PROTOCOL_ERROR);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2038 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2039
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2040 h2c->push_disabled = !value;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2041 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2042
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2043 case NGX_HTTP_V2_MAX_STREAMS_SETTING:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2044 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2045 ngx_http_v2_module);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2046
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2047 h2c->concurrent_pushes = ngx_min(value, h2scf->concurrent_pushes);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2048 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2049
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2050 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2051 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2052 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2053
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2054 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2055 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2056
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2057 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_SETTINGS_ACK_SIZE,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2058 NGX_HTTP_V2_SETTINGS_FRAME,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2059 NGX_HTTP_V2_ACK_FLAG, 0);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2060 if (frame == NULL) {
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2061 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2062 }
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2063
7025
7206c3630310 HTTP/2: don't send SETTINGS ACK before already queued DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 7024
diff changeset
2064 ngx_http_v2_queue_ordered_frame(h2c, frame);
7023
859d80f57aab HTTP/2: send SETTINGS ACK after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7022
diff changeset
2065
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2066 if (window_delta) {
7190
e11a0679d349 HTTP/2: handle duplicate INITIAL_WINDOW_SIZE settings.
Ruslan Ermilov <ru@nginx.com>
parents: 7118
diff changeset
2067 h2c->init_window += window_delta;
e11a0679d349 HTTP/2: handle duplicate INITIAL_WINDOW_SIZE settings.
Ruslan Ermilov <ru@nginx.com>
parents: 7118
diff changeset
2068
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2069 if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) {
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2070 return ngx_http_v2_connection_error(h2c,
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2071 NGX_HTTP_V2_INTERNAL_ERROR);
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2072 }
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2073 }
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2074
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2075 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2076 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2077
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2078
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2079 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2080 ngx_http_v2_state_push_promise(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2081 u_char *end)
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 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2084 "client sent PUSH_PROMISE frame");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2085
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2086 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2087 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2088
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2091 ngx_http_v2_state_ping(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
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 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2094 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2095
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2096 if (h2c->state.length != NGX_HTTP_V2_PING_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2097 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2098 "client sent PING frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2099 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2100
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2101 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2104 if (end - pos < NGX_HTTP_V2_PING_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2105 return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_ping);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2106 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2107
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2108 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
6480
f01ab2dbcfdc Fixed logging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6448
diff changeset
2109 "http2 PING frame, flags: %ud", h2c->state.flags);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2110
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2111 if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2112 return ngx_http_v2_state_skip(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2113 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2114
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2115 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_PING_SIZE,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2116 NGX_HTTP_V2_PING_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2117 NGX_HTTP_V2_ACK_FLAG, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2118 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2119 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2120 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2121
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2122 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2123
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2124 buf->last = ngx_cpymem(buf->last, pos, NGX_HTTP_V2_PING_SIZE);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2125
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2126 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2127
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2128 return ngx_http_v2_state_complete(h2c, pos + NGX_HTTP_V2_PING_SIZE, end);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2132 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2133 ngx_http_v2_state_goaway(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2134 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2135 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2136 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2137 ngx_uint_t last_sid, error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2138 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2139
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2140 if (h2c->state.length < NGX_HTTP_V2_GOAWAY_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2141 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2142 "client sent GOAWAY frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2143 "with incorrect length %uz", h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2144
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2145 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2146 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2147
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2148 if (end - pos < NGX_HTTP_V2_GOAWAY_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2149 return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_goaway);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2150 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2151
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2152 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2153 h2c->state.length -= NGX_HTTP_V2_GOAWAY_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2154
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2155 last_sid = ngx_http_v2_parse_sid(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2156 error = ngx_http_v2_parse_uint32(&pos[4]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2157
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2158 pos += NGX_HTTP_V2_GOAWAY_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2159
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2160 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
2161 "http2 GOAWAY frame: last sid %ui, error %ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2162 last_sid, error);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2163 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2164
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2165 return ngx_http_v2_state_skip(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2166 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2167
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2168
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2169 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2170 ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2171 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2172 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2173 size_t window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2174 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2175 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2176 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2177 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2178
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2179 if (h2c->state.length != NGX_HTTP_V2_WINDOW_UPDATE_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2180 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2181 "client sent WINDOW_UPDATE frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2182 "with incorrect length %uz", h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2183
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2184 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2185 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2186
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2187 if (end - pos < NGX_HTTP_V2_WINDOW_UPDATE_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2188 return ngx_http_v2_state_save(h2c, pos, end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2189 ngx_http_v2_state_window_update);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2190 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2191
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2192 window = ngx_http_v2_parse_window(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2193
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2194 pos += NGX_HTTP_V2_WINDOW_UPDATE_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2195
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2196 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
2197 "http2 WINDOW_UPDATE frame sid:%ui window:%uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2198 h2c->state.sid, window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2199
6988
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2200 if (window == 0) {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2201 if (h2c->state.sid == 0) {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2202 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2203 "client sent WINDOW_UPDATE frame "
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2204 "with incorrect window increment 0");
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2205
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2206 return ngx_http_v2_connection_error(h2c,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2207 NGX_HTTP_V2_PROTOCOL_ERROR);
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2208 }
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2209
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2210 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2211 "client sent WINDOW_UPDATE frame for stream %ui "
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2212 "with incorrect window increment 0", h2c->state.sid);
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2213
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2214 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2215
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2216 if (node && node->stream) {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2217 if (ngx_http_v2_terminate_stream(h2c, node->stream,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2218 NGX_HTTP_V2_PROTOCOL_ERROR)
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2219 == NGX_ERROR)
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2220 {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2221 return ngx_http_v2_connection_error(h2c,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2222 NGX_HTTP_V2_INTERNAL_ERROR);
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2223 }
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2224
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2225 } else {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2226 if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2227 NGX_HTTP_V2_PROTOCOL_ERROR)
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2228 == NGX_ERROR)
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2229 {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2230 return ngx_http_v2_connection_error(h2c,
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2231 NGX_HTTP_V2_INTERNAL_ERROR);
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2232 }
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2233 }
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2234
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2235 return ngx_http_v2_state_complete(h2c, pos, end);
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2236 }
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2237
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2238 if (h2c->state.sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2239 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2240
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2241 if (node == NULL || node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2242 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2243 "unknown http2 stream");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2244
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2245 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2246 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2247
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2248 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2249
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2250 if (window > (size_t) (NGX_HTTP_V2_MAX_WINDOW - stream->send_window)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2251
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2252 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2253 "client violated flow control for stream %ui: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2254 "received WINDOW_UPDATE frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2255 "with window increment %uz "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2256 "not allowed for window %z",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2257 h2c->state.sid, window, stream->send_window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2258
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2259 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2260 NGX_HTTP_V2_FLOW_CTRL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2261 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2262 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2263 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2264 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2265 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2266
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2267 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2268 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2269
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2270 stream->send_window += window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2271
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2272 if (stream->exhausted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2273 stream->exhausted = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2274
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2275 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2276
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2277 wev->active = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2278 wev->ready = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2279
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2280 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2281 wev->handler(wev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2282 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2283 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2284
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2285 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2286 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2287
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2288 if (window > NGX_HTTP_V2_MAX_WINDOW - h2c->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2289 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2290 "client violated connection flow control: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2291 "received WINDOW_UPDATE frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2292 "with window increment %uz "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2293 "not allowed for window %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2294 window, h2c->send_window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2295
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2296 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2297 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2298
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2299 h2c->send_window += window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2300
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2301 while (!ngx_queue_empty(&h2c->waiting)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2302 q = ngx_queue_head(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2303
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2304 ngx_queue_remove(q);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2305
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2306 stream = 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
2307
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6805
diff changeset
2308 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2309
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2310 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2311
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2312 wev->active = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2313 wev->ready = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2314
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2315 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2316 wev->handler(wev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2317
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2318 if (h2c->send_window == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2319 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2320 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2321 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2322 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2323
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2324 return ngx_http_v2_state_complete(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2325 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2326
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2327
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2328 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2329 ngx_http_v2_state_continuation(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2330 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2331 {
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
2332 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
2333 "client sent unexpected CONTINUATION frame");
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
2334
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
2335 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2336 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2337
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2338
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2339 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2340 ngx_http_v2_state_complete(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2341 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2342 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2343 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
2344 "http2 frame complete pos:%p end:%p", pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2345
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2346 if (pos > end) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2347 ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2348 "receive buffer overrun");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2349
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2350 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2351 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2352
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2353 h2c->state.stream = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2354 h2c->state.handler = ngx_http_v2_state_head;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2355
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2356 return pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2357 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2358
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2359
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2360 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2361 ngx_http_v2_state_skip_padded(ngx_http_v2_connection_t *h2c, u_char *pos,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2362 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2363 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2364 h2c->state.length += h2c->state.padding;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2365 h2c->state.padding = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2366
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2367 return ngx_http_v2_state_skip(h2c, pos, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2368 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2369
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2370
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2371 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2372 ngx_http_v2_state_skip(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2373 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2374 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2375
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2376 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2377
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2378 if (size < h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2379 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
2380 "http2 frame skip %uz of %uz", size, h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2381
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2382 h2c->state.length -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2383 return ngx_http_v2_state_save(h2c, end, end, ngx_http_v2_state_skip);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2384 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2385
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2386 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2387 "http2 frame skip %uz", h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2388
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2389 return ngx_http_v2_state_complete(h2c, pos + h2c->state.length, end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2390 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2391
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2392
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2393 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2394 ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2395 ngx_http_v2_handler_pt handler)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2396 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2397 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2398
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2399 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2400 "http2 frame state save pos:%p end:%p handler:%p",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2401 pos, end, handler);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2402
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2403 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2404
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2405 if (size > NGX_HTTP_V2_STATE_BUFFER_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2406 ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2407 "state buffer overflow: %uz bytes required", size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2408
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2409 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2410 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2411
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2412 ngx_memcpy(h2c->state.buffer, pos, NGX_HTTP_V2_STATE_BUFFER_SIZE);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2413
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2414 h2c->state.buffer_used = size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2415 h2c->state.handler = handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2416 h2c->state.incomplete = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2417
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2418 return end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2419 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2420
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2421
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2422 static u_char *
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2423 ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c, u_char *pos,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2424 u_char *end, ngx_http_v2_handler_pt handler)
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2425 {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2426 ngx_event_t *rev;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2427 ngx_http_request_t *r;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2428 ngx_http_core_srv_conf_t *cscf;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2429
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2430 if (h2c->state.stream) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2431 r = h2c->state.stream->request;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2432 rev = r->connection->read;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2433
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2434 if (!rev->timer_set) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2435 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2436 ngx_add_timer(rev, cscf->client_header_timeout);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2437 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2438 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2439
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2440 return ngx_http_v2_state_save(h2c, pos, end, handler);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2441 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2442
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2443
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2444 static u_char *
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2445 ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2446 ngx_uint_t err)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2447 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2448 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2449 "http2 state connection error");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2450
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2451 if (err == NGX_HTTP_V2_INTERNAL_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2452 ngx_debug_point();
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2453 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2454
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2455 ngx_http_v2_finalize_connection(h2c, err);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2456
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2457 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2458 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2459
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2460
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2461 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2462 ngx_http_v2_parse_int(ngx_http_v2_connection_t *h2c, u_char **pos, u_char *end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2463 ngx_uint_t prefix)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2464 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2465 u_char *start, *p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2466 ngx_uint_t value, octet, shift;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2467
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2468 start = *pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2469 p = start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2470
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2471 value = *p++ & prefix;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2472
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2473 if (value != prefix) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2474 if (h2c->state.length == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2475 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2476 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2477
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2478 h2c->state.length--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2479
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2480 *pos = p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2481 return value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2482 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2483
6267
adaac65899c8 HTTP/2: improved HPACK integer parsing code readability.
Ruslan Ermilov <ru@nginx.com>
parents: 6260
diff changeset
2484 if (end - start > NGX_HTTP_V2_INT_OCTETS) {
adaac65899c8 HTTP/2: improved HPACK integer parsing code readability.
Ruslan Ermilov <ru@nginx.com>
parents: 6260
diff changeset
2485 end = start + NGX_HTTP_V2_INT_OCTETS;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2486 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2487
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2488 for (shift = 0; p != end; shift += 7) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2489 octet = *p++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2490
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2491 value += (octet & 0x7f) << shift;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2492
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2493 if (octet < 128) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2494 if ((size_t) (p - start) > h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2495 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2496 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2497
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2498 h2c->state.length -= p - start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2499
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2500 *pos = p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2501 return value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2502 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2503 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2504
6268
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2505 if ((size_t) (end - start) >= h2c->state.length) {
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2506 return NGX_ERROR;
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2507 }
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2508
6267
adaac65899c8 HTTP/2: improved HPACK integer parsing code readability.
Ruslan Ermilov <ru@nginx.com>
parents: 6260
diff changeset
2509 if (end == start + NGX_HTTP_V2_INT_OCTETS) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2510 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2511 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2512
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2513 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2514 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2515
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2516
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2517 ngx_int_t
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2518 ngx_http_v2_push_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t depend,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2519 size_t request_length, ngx_str_t *path, ngx_str_t *authority)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2520 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2521 ngx_int_t rc;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2522 ngx_str_t value;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2523 ngx_connection_t *fc;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2524 ngx_http_request_t *r;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2525 ngx_http_v2_node_t *node;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2526 ngx_http_v2_stream_t *stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2527
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2528 node = ngx_http_v2_get_node_by_id(h2c, h2c->last_push, 1);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2529
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2530 if (node == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2531 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2532 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2533
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2534 if (node->parent) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2535 ngx_queue_remove(&node->reuse);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2536 h2c->closed_nodes--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2537 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2538
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2539 stream = ngx_http_v2_create_stream(h2c, 1);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2540 if (stream == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2541 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2542 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2543
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2544 stream->pool = ngx_create_pool(1024, h2c->connection->log);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2545 if (stream->pool == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2546 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2547 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2548
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2549 r = stream->request;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2550 fc = r->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2551
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2552 r->request_length = request_length;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2553
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2554 stream->in_closed = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2555 stream->node = node;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2556
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2557 node->stream = stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2558
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2559 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2560 "http2 push stream sid:%ui "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2561 "depends on %ui excl:0 weight:16",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2562 h2c->last_push, depend);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2563
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2564 node->weight = NGX_HTTP_V2_DEFAULT_WEIGHT;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2565 ngx_http_v2_set_dependency(h2c, node, depend, 0);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2566
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2567 r->method_name = ngx_http_core_get_method;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2568 r->method = NGX_HTTP_GET;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2569
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2570 r->schema_start = (u_char *) "https";
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2571
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2572 #if (NGX_HTTP_SSL)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2573 if (fc->ssl) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2574 r->schema_end = r->schema_start + 5;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2575
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2576 } else
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2577 #endif
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2578 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2579 r->schema_end = r->schema_start + 4;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2580 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2581
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2582 value.len = authority->len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2583
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2584 value.data = ngx_pstrdup(stream->pool, authority);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2585 if (value.data == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2586 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2587 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2588
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2589 rc = ngx_http_v2_parse_authority(r, &value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2590
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2591 if (rc != NGX_OK) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2592 goto error;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2593 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2594
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2595 value.len = path->len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2596
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2597 value.data = ngx_pstrdup(stream->pool, path);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2598 if (value.data == NULL) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2599 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2600 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2601
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2602 rc = ngx_http_v2_parse_path(r, &value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2603
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2604 if (rc != NGX_OK) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2605 goto error;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2606 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2607
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2608 fc->write->handler = ngx_http_v2_run_request_handler;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2609 ngx_post_event(fc->write, &ngx_posted_events);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2610
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2611 return NGX_OK;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2612
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2613 error:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2614
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2615 if (rc == NGX_ABORT) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2616 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2617 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2618
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2619 if (rc == NGX_DECLINED) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2620 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2621 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2622 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2623
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2624 (void) ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2625
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2626 return NGX_ERROR;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2627 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2628
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2629
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2630 static ngx_int_t
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2631 ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2632 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2633 size_t len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2634 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2635 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2636 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2637 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2638
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2639 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2640 "http2 send SETTINGS frame");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2641
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2642 frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2643 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2644 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2645 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2646
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2647 cl = ngx_alloc_chain_link(h2c->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2648 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2649 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2650 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2651
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2652 len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2653
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2654 buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2655 if (buf == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2656 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2657 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2658
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2659 buf->last_buf = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2660
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2661 cl->buf = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2662 cl->next = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2663
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2664 frame->first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2665 frame->last = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2666 frame->handler = ngx_http_v2_settings_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2667 frame->stream = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2668 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2669 frame->length = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2670 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2671 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2672
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2673 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
2674 NGX_HTTP_V2_SETTINGS_FRAME);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2675
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2676 *buf->last++ = NGX_HTTP_V2_NO_FLAG;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2677
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2678 buf->last = ngx_http_v2_write_sid(buf->last, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2679
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2680 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2681 ngx_http_v2_module);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2682
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2683 buf->last = ngx_http_v2_write_uint16(buf->last,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2684 NGX_HTTP_V2_MAX_STREAMS_SETTING);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2685 buf->last = ngx_http_v2_write_uint32(buf->last,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2686 h2scf->concurrent_streams);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2687
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2688 buf->last = ngx_http_v2_write_uint16(buf->last,
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2689 NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING);
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2690 buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2691
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2692 buf->last = ngx_http_v2_write_uint16(buf->last,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2693 NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2694 buf->last = ngx_http_v2_write_uint32(buf->last,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2695 NGX_HTTP_V2_MAX_FRAME_SIZE);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2696
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2697 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2698
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2699 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2700 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2701
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2702
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2703 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2704 ngx_http_v2_settings_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2705 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2706 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2707 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2708
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2709 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2710
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2711 if (buf->pos != buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2712 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2713 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2714
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2715 ngx_free_chain(h2c->pool, frame->first);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2716
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2717 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2718 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2719
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2720
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2721 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2722 ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c, ngx_uint_t sid,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2723 size_t window)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2724 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2725 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2726 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2727
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2728 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2729 "http2 send WINDOW_UPDATE frame sid:%ui, window:%uz",
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2730 sid, window);
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2731
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2732 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_WINDOW_UPDATE_SIZE,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2733 NGX_HTTP_V2_WINDOW_UPDATE_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2734 NGX_HTTP_V2_NO_FLAG, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2735 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2736 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2737 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2738
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2739 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2740
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2741 buf->last = ngx_http_v2_write_uint32(buf->last, window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2742
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2743 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2744
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2745 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2746 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2747
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2748
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2749 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2750 ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t sid,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2751 ngx_uint_t status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2752 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2753 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2754 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2755
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2756 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
6790
727c6412673a HTTP/2: slightly improved debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 6783
diff changeset
2757 "http2 send RST_STREAM frame sid:%ui, status:%ui",
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2758 sid, status);
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2759
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2760 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_RST_STREAM_SIZE,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2761 NGX_HTTP_V2_RST_STREAM_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2762 NGX_HTTP_V2_NO_FLAG, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2763 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2764 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2765 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2766
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2767 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2768
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2769 buf->last = ngx_http_v2_write_uint32(buf->last, status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2770
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2771 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2772
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2773 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2774 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2775
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2776
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2777 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2778 ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c, ngx_uint_t status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2779 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2780 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2781 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2782
6790
727c6412673a HTTP/2: slightly improved debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 6783
diff changeset
2783 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
727c6412673a HTTP/2: slightly improved debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 6783
diff changeset
2784 "http2 send GOAWAY frame: last sid %ui, error %ui",
727c6412673a HTTP/2: slightly improved debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 6783
diff changeset
2785 h2c->last_sid, status);
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2786
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2787 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_GOAWAY_SIZE,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2788 NGX_HTTP_V2_GOAWAY_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2789 NGX_HTTP_V2_NO_FLAG, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2790 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2791 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2792 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2793
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2794 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2795
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2796 buf->last = ngx_http_v2_write_sid(buf->last, h2c->last_sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2797 buf->last = ngx_http_v2_write_uint32(buf->last, status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2798
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2799 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2800
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2801 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2802 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2803
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2804
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2805 static ngx_http_v2_out_frame_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2806 ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2807 ngx_uint_t type, u_char flags, ngx_uint_t sid)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2808 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2809 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2810 ngx_pool_t *pool;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2811 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2812
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2813 frame = h2c->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2814
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2815 if (frame) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2816 h2c->free_frames = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2817
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2818 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2819 buf->pos = buf->start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2820
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2821 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2822
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2823 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2824 pool = h2c->pool ? h2c->pool : h2c->connection->pool;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2825
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2826 frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2827 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2828 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2829 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2830
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2831 frame->first = ngx_alloc_chain_link(pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2832 if (frame->first == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2833 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2834 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2835
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2836 buf = ngx_create_temp_buf(pool, NGX_HTTP_V2_FRAME_BUFFER_SIZE);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2837 if (buf == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2838 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2839 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2840
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2841 buf->last_buf = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2842
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2843 frame->first->buf = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2844 frame->last = frame->first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2845
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2846 frame->handler = ngx_http_v2_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2847 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2848
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2849 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2850 if (length > NGX_HTTP_V2_FRAME_BUFFER_SIZE - NGX_HTTP_V2_FRAME_HEADER_SIZE)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2851 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2852 ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2853 "requested control frame is too large: %uz", length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2854 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2855 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2856
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2857 frame->length = length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2858 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2859
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2860 buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2861
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2862 *buf->last++ = flags;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2863
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2864 buf->last = ngx_http_v2_write_sid(buf->last, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2865
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2866 return frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2867 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2868
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2869
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2870 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2871 ngx_http_v2_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2872 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2873 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2874 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2875
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2876 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2877
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2878 if (buf->pos != buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2879 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2880 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2881
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2882 frame->next = h2c->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2883 h2c->free_frames = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2884
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2885 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2886 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2887
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2888
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2889 static ngx_http_v2_stream_t *
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2890 ngx_http_v2_create_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t push)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2891 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2892 ngx_log_t *log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2893 ngx_event_t *rev, *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2894 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2895 ngx_http_log_ctx_t *ctx;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2896 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2897 ngx_http_v2_stream_t *stream;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
2898 ngx_http_v2_srv_conf_t *h2scf;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2899 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2900
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2901 fc = h2c->free_fake_connections;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2902
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2903 if (fc) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2904 h2c->free_fake_connections = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2905
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2906 rev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2907 wev = fc->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2908 log = fc->log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2909 ctx = log->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2910
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2911 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2912 fc = ngx_palloc(h2c->pool, sizeof(ngx_connection_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2913 if (fc == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2914 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2915 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2916
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2917 rev = ngx_palloc(h2c->pool, sizeof(ngx_event_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2918 if (rev == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2919 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2920 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2921
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2922 wev = ngx_palloc(h2c->pool, sizeof(ngx_event_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2923 if (wev == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2924 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2925 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2926
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2927 log = ngx_palloc(h2c->pool, sizeof(ngx_log_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2928 if (log == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2929 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2930 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2931
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2932 ctx = ngx_palloc(h2c->pool, sizeof(ngx_http_log_ctx_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2933 if (ctx == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2934 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2935 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2936
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2937 ctx->connection = fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2938 ctx->request = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2939 ctx->current_request = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2940 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2941
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2942 ngx_memcpy(log, h2c->connection->log, sizeof(ngx_log_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2943
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2944 log->data = ctx;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2945
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2946 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2947 log->action = "processing pushed request headers";
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2948
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2949 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2950 log->action = "reading client request headers";
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2951 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2952
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2953 ngx_memzero(rev, sizeof(ngx_event_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2954
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2955 rev->data = fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2956 rev->ready = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2957 rev->handler = ngx_http_v2_close_stream_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2958 rev->log = log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2959
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2960 ngx_memcpy(wev, rev, sizeof(ngx_event_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2961
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2962 wev->write = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2963
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2964 ngx_memcpy(fc, h2c->connection, sizeof(ngx_connection_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2965
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2966 fc->data = h2c->http_connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2967 fc->read = rev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2968 fc->write = wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2969 fc->sent = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2970 fc->log = log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2971 fc->buffered = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2972 fc->sndlowat = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2973 fc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2974
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2975 r = ngx_http_create_request(fc);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2976 if (r == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2977 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2978 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2979
6256
9dfc4ba140f9 HTTP/2: fixed $server_protocol value (ticket #800).
Valentin Bartenev <vbart@nginx.com>
parents: 6249
diff changeset
2980 ngx_str_set(&r->http_protocol, "HTTP/2.0");
9dfc4ba140f9 HTTP/2: fixed $server_protocol value (ticket #800).
Valentin Bartenev <vbart@nginx.com>
parents: 6249
diff changeset
2981
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2982 r->http_version = NGX_HTTP_VERSION_20;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2983 r->valid_location = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2984
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2985 fc->data = r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2986 h2c->connection->requests++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2987
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2988 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
2989
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2990 r->header_in = ngx_create_temp_buf(r->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2991 cscf->client_header_buffer_size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2992 if (r->header_in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2993 ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2994 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2995 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2996
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2997 if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2998 sizeof(ngx_table_elt_t))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2999 != NGX_OK)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3000 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3001 ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3002 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3003 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3004
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3005 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3006
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3007 stream = ngx_pcalloc(r->pool, sizeof(ngx_http_v2_stream_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3008 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3009 ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3010 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3011 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3012
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3013 r->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3014
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3015 stream->request = r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3016 stream->connection = h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3017
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3018 h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3019
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3020 stream->send_window = h2c->init_window;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3021 stream->recv_window = h2scf->preread_size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3022
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3023 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3024 h2c->pushing++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3025
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3026 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3027 h2c->processing++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3028 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3029
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3030 return stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3031 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3032
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3033
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3034 static ngx_http_v2_node_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3035 ngx_http_v2_get_node_by_id(ngx_http_v2_connection_t *h2c, ngx_uint_t sid,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3036 ngx_uint_t alloc)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3037 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3038 ngx_uint_t index;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3039 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3040 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3041
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3042 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3043 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3044
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3045 index = ngx_http_v2_index(h2scf, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3046
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3047 for (node = h2c->streams_index[index]; node; node = node->index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3048
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3049 if (node->id == sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3050 return node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3051 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3052 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3053
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3054 if (!alloc) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3055 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3056 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3057
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3058 if (h2c->closed_nodes < 32) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3059 node = ngx_pcalloc(h2c->connection->pool, sizeof(ngx_http_v2_node_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3060 if (node == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3061 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3062 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3063
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3064 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3065 node = ngx_http_v2_get_closed_node(h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3066 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3067
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3068 node->id = sid;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3069
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3070 ngx_queue_init(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3071
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3072 node->index = h2c->streams_index[index];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3073 h2c->streams_index[index] = node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3074
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3075 return node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3076 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3077
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3078
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3079 static ngx_http_v2_node_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3080 ngx_http_v2_get_closed_node(ngx_http_v2_connection_t *h2c)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3081 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3082 ngx_uint_t weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3083 ngx_queue_t *q, *children;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3084 ngx_http_v2_node_t *node, **next, *n, *parent, *child;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3085 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3086
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3087 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3088 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3089
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3090 h2c->closed_nodes--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3091
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3092 q = ngx_queue_head(&h2c->closed);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3093
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3094 ngx_queue_remove(q);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3095
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3096 node = ngx_queue_data(q, ngx_http_v2_node_t, reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3097
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3098 next = &h2c->streams_index[ngx_http_v2_index(h2scf, node->id)];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3099
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3100 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3101 n = *next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3102
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3103 if (n == node) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3104 *next = n->index;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3105 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3106 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3107
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3108 next = &n->index;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3109 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3110
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3111 ngx_queue_remove(&node->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3112
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3113 weight = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3114
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3115 for (q = ngx_queue_head(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3116 q != ngx_queue_sentinel(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3117 q = ngx_queue_next(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3118 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3119 child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3120 weight += child->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3121 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3122
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
3123 parent = node->parent;
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
3124
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3125 for (q = ngx_queue_head(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3126 q != ngx_queue_sentinel(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3127 q = ngx_queue_next(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3128 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3129 child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
3130 child->parent = parent;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3131 child->weight = node->weight * child->weight / weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3132
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3133 if (child->weight == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3134 child->weight = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3135 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3136 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3137
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3138 if (parent == NGX_HTTP_V2_ROOT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3139 node->rank = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3140 node->rel_weight = 1.0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3141
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3142 children = &h2c->dependencies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3143
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3144 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3145 node->rank = parent->rank;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3146 node->rel_weight = parent->rel_weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3147
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3148 children = &parent->children;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3149 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3150
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3151 ngx_http_v2_node_children_update(node);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3152 ngx_queue_add(children, &node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3153
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3154 ngx_memzero(node, sizeof(ngx_http_v2_node_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3155
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3156 return node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3157 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3158
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3159
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3160 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3161 ngx_http_v2_validate_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3162 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3163 u_char ch;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3164 ngx_uint_t i;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3165 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3166
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3167 if (header->name.len == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3168 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3169 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3170
6291
932a465537ef HTTP/2: fixed invalid headers handling (ticket #831).
Valentin Bartenev <vbart@nginx.com>
parents: 6288
diff changeset
3171 r->invalid_header = 0;
932a465537ef HTTP/2: fixed invalid headers handling (ticket #831).
Valentin Bartenev <vbart@nginx.com>
parents: 6288
diff changeset
3172
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3173 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
3174
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3175 for (i = (header->name.data[0] == ':'); i != header->name.len; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3176 ch = header->name.data[i];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3177
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3178 if ((ch >= 'a' && ch <= 'z')
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3179 || (ch == '-')
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3180 || (ch >= '0' && ch <= '9')
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3181 || (ch == '_' && cscf->underscores_in_headers))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3182 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3183 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3184 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3185
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3186 switch (ch) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3187 case '\0':
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3188 case LF:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3189 case CR:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3190 case ':':
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3191 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3192 "client sent invalid header name: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3193 &header->name);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3194
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3195 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3196 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3197
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3198 if (ch >= 'A' && ch <= 'Z') {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3199 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3200 "client sent invalid header name: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3201 &header->name);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3202
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3203 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3204 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3205
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3206 r->invalid_header = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3207 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3208
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3209 for (i = 0; i != header->value.len; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3210 ch = header->value.data[i];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3211
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3212 switch (ch) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3213 case '\0':
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3214 case LF:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3215 case CR:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3216 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3217 "client sent header \"%V\" with "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3218 "invalid value: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3219 &header->name, &header->value);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3220
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3221 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3222 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3223 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3224
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3225 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3226 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3227
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3228
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3229 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3230 ngx_http_v2_pseudo_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3231 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3232 header->name.len--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3233 header->name.data++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3234
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3235 switch (header->name.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3236 case 4:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3237 if (ngx_memcmp(header->name.data, "path", sizeof("path") - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3238 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3239 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3240 return ngx_http_v2_parse_path(r, &header->value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3241 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3242
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3243 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3244
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3245 case 6:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3246 if (ngx_memcmp(header->name.data, "method", sizeof("method") - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3247 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3248 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3249 return ngx_http_v2_parse_method(r, &header->value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3250 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3251
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3252 if (ngx_memcmp(header->name.data, "scheme", sizeof("scheme") - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3253 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3254 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3255 return ngx_http_v2_parse_scheme(r, &header->value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3256 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3257
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3258 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3259
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3260 case 9:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3261 if (ngx_memcmp(header->name.data, "authority", sizeof("authority") - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3262 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3263 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3264 return ngx_http_v2_parse_authority(r, &header->value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3265 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3266
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3267 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3268 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3269
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3270 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
3271 "client sent unknown pseudo-header \":%V\"",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3272 &header->name);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3273
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3274 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3275 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3276
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3277
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3278 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3279 ngx_http_v2_parse_path(ngx_http_request_t *r, ngx_str_t *value)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3280 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3281 if (r->unparsed_uri.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3282 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3283 "client sent duplicate :path header");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3284
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3285 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3286 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3287
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3288 if (value->len == 0) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3289 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3290 "client sent empty :path header");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3291
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3292 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3293 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3294
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3295 r->uri_start = value->data;
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3296 r->uri_end = value->data + value->len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3297
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3298 if (ngx_http_parse_uri(r) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3299 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3300 "client sent invalid :path header: \"%V\"", value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3301
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3302 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3303 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3304
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3305 if (ngx_http_process_request_uri(r) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3306 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3307 * request has been finalized already
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3308 * in ngx_http_process_request_uri()
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3309 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3310 return NGX_ABORT;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3311 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3312
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3313 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3314 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3315
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3316
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3317 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3318 ngx_http_v2_parse_method(ngx_http_request_t *r, ngx_str_t *value)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3319 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3320 size_t k, len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3321 ngx_uint_t n;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3322 const u_char *p, *m;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3323
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3324 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3325 * This array takes less than 256 sequential bytes,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3326 * and if typical CPU cache line size is 64 bytes,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3327 * it is prefetched for 4 load operations.
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3328 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3329 static const struct {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3330 u_char len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3331 const u_char method[11];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3332 uint32_t value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3333 } tests[] = {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3334 { 3, "GET", NGX_HTTP_GET },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3335 { 4, "POST", NGX_HTTP_POST },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3336 { 4, "HEAD", NGX_HTTP_HEAD },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3337 { 7, "OPTIONS", NGX_HTTP_OPTIONS },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3338 { 8, "PROPFIND", NGX_HTTP_PROPFIND },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3339 { 3, "PUT", NGX_HTTP_PUT },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3340 { 5, "MKCOL", NGX_HTTP_MKCOL },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3341 { 6, "DELETE", NGX_HTTP_DELETE },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3342 { 4, "COPY", NGX_HTTP_COPY },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3343 { 4, "MOVE", NGX_HTTP_MOVE },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3344 { 9, "PROPPATCH", NGX_HTTP_PROPPATCH },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3345 { 4, "LOCK", NGX_HTTP_LOCK },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3346 { 6, "UNLOCK", NGX_HTTP_UNLOCK },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3347 { 5, "PATCH", NGX_HTTP_PATCH },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3348 { 5, "TRACE", NGX_HTTP_TRACE }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3349 }, *test;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3350
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3351 if (r->method_name.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3352 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3353 "client sent duplicate :method header");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3354
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3355 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3356 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3357
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3358 if (value->len == 0) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3359 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3360 "client sent empty :method header");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3361
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3362 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3363 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3364
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3365 r->method_name.len = value->len;
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3366 r->method_name.data = value->data;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3367
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3368 len = r->method_name.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3369 n = sizeof(tests) / sizeof(tests[0]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3370 test = tests;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3371
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3372 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3373 if (len == test->len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3374 p = r->method_name.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3375 m = test->method;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3376 k = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3377
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3378 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3379 if (*p++ != *m++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3380 goto next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3381 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3382 } while (--k);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3383
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3384 r->method = test->value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3385 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3386 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3387
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3388 next:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3389 test++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3390
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3391 } while (--n);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3392
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3393 p = r->method_name.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3394
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3395 do {
6732
57148b755320 Allowed '-' in method names.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6642
diff changeset
3396 if ((*p < 'A' || *p > 'Z') && *p != '_' && *p != '-') {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3397 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3398 "client sent invalid method: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3399 &r->method_name);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3400
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3401 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3402 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3403
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3404 p++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3405
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3406 } while (--len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3407
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3408 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3409 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3410
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3411
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3412 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3413 ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3414 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3415 if (r->schema_start) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3416 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
3417 "client sent duplicate :scheme header");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3418
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3419 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3420 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3421
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3422 if (value->len == 0) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3423 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
3424 "client sent empty :scheme header");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3425
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3426 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3427 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3428
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3429 r->schema_start = value->data;
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3430 r->schema_end = value->data + value->len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3431
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3432 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3433 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3434
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3435
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3436 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3437 ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3438 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3439 ngx_table_elt_t *h;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3440 ngx_http_header_t *hh;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3441 ngx_http_core_main_conf_t *cmcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3442
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3443 static ngx_str_t host = ngx_string("host");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3444
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3445 h = ngx_list_push(&r->headers_in.headers);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3446 if (h == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3447 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3448 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3449
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3450 h->hash = ngx_hash_key(host.data, host.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3451
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3452 h->key.len = host.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3453 h->key.data = host.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3454
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3455 h->value.len = value->len;
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3456 h->value.data = value->data;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3457
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3458 h->lowcase_key = host.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3459
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3460 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3461
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3462 hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3463 h->lowcase_key, h->key.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3464
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3465 if (hh == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3466 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3467 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3468
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3469 if (hh->handler(r, h, hh->offset) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3470 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3471 * request has been finalized already
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3472 * in ngx_http_process_host()
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3473 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3474 return NGX_ABORT;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3475 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3476
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3477 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3478 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3479
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3480
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3481 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3482 ngx_http_v2_construct_request_line(ngx_http_request_t *r)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3483 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3484 u_char *p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3485
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3486 static const u_char ending[] = " HTTP/2.0";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3487
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3488 if (r->method_name.len == 0
7029
3c55863e6887 HTTP/2: reject HTTP/2 requests without ":scheme" pseudo-header.
Piotr Sikora <piotrsikora@google.com>
parents: 7025
diff changeset
3489 || r->schema_start == NULL
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3490 || r->unparsed_uri.len == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3491 {
7106
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3492 if (r->method_name.len == 0) {
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3493 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3494 "client sent no :method header");
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3495
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3496 } else if (r->schema_start == NULL) {
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3497 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
3498 "client sent no :scheme header");
7106
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3499
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3500 } else {
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3501 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3502 "client sent no :path header");
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3503 }
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3504
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3505 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3506 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3507 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3508
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3509 r->request_line.len = r->method_name.len + 1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3510 + r->unparsed_uri.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3511 + sizeof(ending) - 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3512
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3513 p = ngx_pnalloc(r->pool, r->request_line.len + 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3514 if (p == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3515 ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3516 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3517 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3518
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3519 r->request_line.data = p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3520
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3521 p = ngx_cpymem(p, r->method_name.data, r->method_name.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3522
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3523 *p++ = ' ';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3524
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3525 p = ngx_cpymem(p, r->unparsed_uri.data, r->unparsed_uri.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3526
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3527 ngx_memcpy(p, ending, sizeof(ending));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3528
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3529 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
7108
2bf605c6edf7 HTTP/2: shortened some debug log messages.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7106
diff changeset
3530 "http2 request line: \"%V\"", &r->request_line);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3531
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3532 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3533 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3534
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3535
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3536 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3537 ngx_http_v2_cookie(ngx_http_request_t *r, ngx_http_v2_header_t *header)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3538 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3539 ngx_str_t *val;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3540 ngx_array_t *cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3541
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3542 cookies = r->stream->cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3543
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3544 if (cookies == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3545 cookies = ngx_array_create(r->pool, 2, sizeof(ngx_str_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3546 if (cookies == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3547 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3548 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3549
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3550 r->stream->cookies = cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3551 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3552
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3553 val = ngx_array_push(cookies);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3554 if (val == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3555 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3556 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3557
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3558 val->len = header->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3559 val->data = header->value.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3560
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3561 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3562 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3563
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3564
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3565 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3566 ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3567 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3568 u_char *buf, *p, *end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3569 size_t len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3570 ngx_str_t *vals;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3571 ngx_uint_t i;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3572 ngx_array_t *cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3573 ngx_table_elt_t *h;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3574 ngx_http_header_t *hh;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3575 ngx_http_core_main_conf_t *cmcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3576
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3577 static ngx_str_t cookie = ngx_string("cookie");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3578
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3579 cookies = r->stream->cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3580
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3581 if (cookies == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3582 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3583 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3584
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3585 vals = cookies->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3586
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3587 i = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3588 len = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3589
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3590 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3591 len += vals[i].len + 2;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3592 } while (++i != cookies->nelts);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3593
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3594 len -= 2;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3595
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3596 buf = ngx_pnalloc(r->pool, len + 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3597 if (buf == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3598 ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3599 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3600 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3601
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3602 p = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3603 end = buf + len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3604
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3605 for (i = 0; /* void */ ; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3606
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3607 p = ngx_cpymem(p, vals[i].data, vals[i].len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3608
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3609 if (p == end) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3610 *p = '\0';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3611 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3612 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3613
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3614 *p++ = ';'; *p++ = ' ';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3615 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3616
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3617 h = ngx_list_push(&r->headers_in.headers);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3618 if (h == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3619 ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3620 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3621 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3622
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3623 h->hash = ngx_hash_key(cookie.data, cookie.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3624
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3625 h->key.len = cookie.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3626 h->key.data = cookie.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3627
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3628 h->value.len = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3629 h->value.data = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3630
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3631 h->lowcase_key = cookie.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3632
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3633 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3634
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3635 hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3636 h->lowcase_key, h->key.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3637
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3638 if (hh == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3639 ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3640 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3641 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3642
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3643 if (hh->handler(r, h, hh->offset) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3644 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3645 * request has been finalized already
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3646 * in ngx_http_process_multi_header_lines()
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3647 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3648 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3649 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3650
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3651 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3652 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3653
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3654
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3655 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3656 ngx_http_v2_run_request(ngx_http_request_t *r)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3657 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3658 if (ngx_http_v2_construct_request_line(r) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3659 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3660 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3661
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3662 if (ngx_http_v2_construct_cookie_header(r) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3663 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3664 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3665
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3666 r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3667
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3668 if (ngx_http_process_request_header(r) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3669 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3670 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3671
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3672 if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3673 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3674 "client prematurely closed stream");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3675
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3676 r->stream->skip_data = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3677
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3678 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3679 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3680 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3681
6589
78533a74af11 HTTP/2: avoid adding Content-Length for requests without body.
Valentin Bartenev <vbart@nginx.com>
parents: 6588
diff changeset
3682 if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
78533a74af11 HTTP/2: avoid adding Content-Length for requests without body.
Valentin Bartenev <vbart@nginx.com>
parents: 6588
diff changeset
3683 r->headers_in.chunked = 1;
78533a74af11 HTTP/2: avoid adding Content-Length for requests without body.
Valentin Bartenev <vbart@nginx.com>
parents: 6588
diff changeset
3684 }
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3685
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3686 ngx_http_process_request(r);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3687 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3688
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3689
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3690 static void
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3691 ngx_http_v2_run_request_handler(ngx_event_t *ev)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3692 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3693 ngx_connection_t *fc;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3694 ngx_http_request_t *r;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3695
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3696 fc = ev->data;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3697 r = fc->data;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3698
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3699 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3700 "http2 run request handler");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3701
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3702 ngx_http_v2_run_request(r);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3703 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3704
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3705
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3706 ngx_int_t
6989
2c4dbcd6f2e4 HTTP/2: reduced difference to HTTP/1.x in reading request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6988
diff changeset
3707 ngx_http_v2_read_request_body(ngx_http_request_t *r)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3708 {
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3709 off_t len;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3710 size_t size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3711 ngx_buf_t *buf;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3712 ngx_int_t rc;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
3713 ngx_http_v2_stream_t *stream;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3714 ngx_http_v2_srv_conf_t *h2scf;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3715 ngx_http_request_body_t *rb;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
3716 ngx_http_core_loc_conf_t *clcf;
6520
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3717 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3718
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3719 stream = r->stream;
6989
2c4dbcd6f2e4 HTTP/2: reduced difference to HTTP/1.x in reading request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6988
diff changeset
3720 rb = r->request_body;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3721
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3722 if (stream->skip_data) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3723 r->request_body_no_buffering = 0;
6989
2c4dbcd6f2e4 HTTP/2: reduced difference to HTTP/1.x in reading request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6988
diff changeset
3724 rb->post_handler(r);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3725 return NGX_OK;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3726 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3727
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3728 h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3729 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3730
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3731 len = r->headers_in.content_length_n;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3732
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3733 if (r->request_body_no_buffering && !stream->in_closed) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3734
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3735 if (len < 0 || len > (off_t) clcf->client_body_buffer_size) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3736 len = clcf->client_body_buffer_size;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3737 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3738
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3739 /*
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3740 * We need a room to store data up to the stream's initial window size,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3741 * at least until this window will be exhausted.
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3742 */
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3743
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3744 if (len < (off_t) h2scf->preread_size) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3745 len = h2scf->preread_size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3746 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3747
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3748 if (len > NGX_HTTP_V2_MAX_WINDOW) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3749 len = NGX_HTTP_V2_MAX_WINDOW;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3750 }
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3751
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3752 rb->buf = ngx_create_temp_buf(r->pool, (size_t) len);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3753
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3754 } else if (len >= 0 && len <= (off_t) clcf->client_body_buffer_size
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3755 && !r->request_body_in_file_only)
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3756 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3757 rb->buf = ngx_create_temp_buf(r->pool, (size_t) len);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3758
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3759 } else {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3760 rb->buf = ngx_calloc_buf(r->pool);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3761
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3762 if (rb->buf != NULL) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3763 rb->buf->sync = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3764 }
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3765 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3766
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3767 if (rb->buf == NULL) {
6519
9ac934dd5dd8 HTTP/2: skip data frames in case of internal errors.
Valentin Bartenev <vbart@nginx.com>
parents: 6518
diff changeset
3768 stream->skip_data = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3769 return NGX_HTTP_INTERNAL_SERVER_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3770 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3771
6989
2c4dbcd6f2e4 HTTP/2: reduced difference to HTTP/1.x in reading request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6988
diff changeset
3772 rb->rest = 1;
2c4dbcd6f2e4 HTTP/2: reduced difference to HTTP/1.x in reading request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6988
diff changeset
3773
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3774 buf = stream->preread;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3775
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3776 if (stream->in_closed) {
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3777 r->request_body_no_buffering = 0;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3778
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3779 if (buf) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3780 rc = ngx_http_v2_process_request_body(r, buf->pos,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3781 buf->last - buf->pos, 1);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3782 ngx_pfree(r->pool, buf->start);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3783 return rc;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3784 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3785
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3786 return ngx_http_v2_process_request_body(r, NULL, 0, 1);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3787 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3788
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3789 if (buf) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3790 rc = ngx_http_v2_process_request_body(r, buf->pos,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3791 buf->last - buf->pos, 0);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3792
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3793 ngx_pfree(r->pool, buf->start);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3794
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3795 if (rc != NGX_OK) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3796 stream->skip_data = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3797 return rc;
6518
7760b54d5458 HTTP/2: don't send WINDOW_UPDATE for an empty request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6516
diff changeset
3798 }
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3799 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3800
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3801 if (r->request_body_no_buffering) {
6572
bc6fd7afeed6 HTTP/2: unbreak build on MSVC.
Valentin Bartenev <vbart@nginx.com>
parents: 6566
diff changeset
3802 size = (size_t) len - h2scf->preread_size;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3803
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3804 } else {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3805 stream->no_flow_control = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3806 size = NGX_HTTP_V2_MAX_WINDOW - stream->recv_window;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3807 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3808
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3809 if (size) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3810 if (ngx_http_v2_send_window_update(stream->connection,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3811 stream->node->id, size)
6518
7760b54d5458 HTTP/2: don't send WINDOW_UPDATE for an empty request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6516
diff changeset
3812 == NGX_ERROR)
7760b54d5458 HTTP/2: don't send WINDOW_UPDATE for an empty request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6516
diff changeset
3813 {
6519
9ac934dd5dd8 HTTP/2: skip data frames in case of internal errors.
Valentin Bartenev <vbart@nginx.com>
parents: 6518
diff changeset
3814 stream->skip_data = 1;
6518
7760b54d5458 HTTP/2: don't send WINDOW_UPDATE for an empty request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6516
diff changeset
3815 return NGX_HTTP_INTERNAL_SERVER_ERROR;
7760b54d5458 HTTP/2: don't send WINDOW_UPDATE for an empty request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6516
diff changeset
3816 }
6520
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3817
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3818 h2c = stream->connection;
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3819
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3820 if (!h2c->blocked) {
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3821 if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3822 stream->skip_data = 1;
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3823 return NGX_HTTP_INTERNAL_SERVER_ERROR;
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3824 }
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
3825 }
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3826
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3827 stream->recv_window += size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3828 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3829
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3830 if (!buf) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3831 ngx_add_timer(r->connection->read, clcf->client_body_timeout);
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3832 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3833
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
3834 r->read_event_handler = ngx_http_v2_read_client_request_body_handler;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3835 r->write_event_handler = ngx_http_request_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3836
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3837 return NGX_AGAIN;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3838 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3839
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3840
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3841 static ngx_int_t
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3842 ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3843 size_t size, ngx_uint_t last)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3844 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3845 ngx_buf_t *buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3846 ngx_int_t rc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3847 ngx_connection_t *fc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3848 ngx_http_request_body_t *rb;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3849 ngx_http_core_loc_conf_t *clcf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3850
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3851 fc = r->connection;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3852 rb = r->request_body;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3853 buf = rb->buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3854
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3855 if (size) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3856 if (buf->sync) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3857 buf->pos = buf->start = pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3858 buf->last = buf->end = pos + size;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3859
7118
b6dc472299da HTTP/2: enforce writing the sync request body buffer to file.
Valentin Bartenev <vbart@nginx.com>
parents: 7108
diff changeset
3860 r->request_body_in_file_only = 1;
b6dc472299da HTTP/2: enforce writing the sync request body buffer to file.
Valentin Bartenev <vbart@nginx.com>
parents: 7108
diff changeset
3861
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3862 } else {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3863 if (size > (size_t) (buf->end - buf->last)) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3864 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3865 "client intended to send body data "
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3866 "larger than declared");
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3867
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3868 return NGX_HTTP_BAD_REQUEST;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3869 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3870
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3871 buf->last = ngx_cpymem(buf->last, pos, size);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3872 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3873 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3874
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3875 if (last) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3876 rb->rest = 0;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3877
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3878 if (fc->read->timer_set) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3879 ngx_del_timer(fc->read);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3880 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3881
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3882 if (r->request_body_no_buffering) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3883 ngx_post_event(fc->read, &ngx_posted_events);
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3884 return NGX_OK;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3885 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3886
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3887 rc = ngx_http_v2_filter_request_body(r);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3888
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3889 if (rc != NGX_OK) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3890 return rc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3891 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3892
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3893 if (buf->sync) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3894 /* prevent reusing this buffer in the upstream module */
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3895 rb->buf = NULL;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3896 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3897
6589
78533a74af11 HTTP/2: avoid adding Content-Length for requests without body.
Valentin Bartenev <vbart@nginx.com>
parents: 6588
diff changeset
3898 if (r->headers_in.chunked) {
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3899 r->headers_in.content_length_n = rb->received;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3900 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3901
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3902 r->read_event_handler = ngx_http_block_reading;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3903 rb->post_handler(r);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3904
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3905 return NGX_OK;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3906 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3907
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3908 if (size == 0) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3909 return NGX_OK;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3910 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3911
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
3912 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3913 ngx_add_timer(fc->read, clcf->client_body_timeout);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3914
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3915 if (r->request_body_no_buffering) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3916 ngx_post_event(fc->read, &ngx_posted_events);
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3917 return NGX_OK;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3918 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3919
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3920 if (buf->sync) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3921 return ngx_http_v2_filter_request_body(r);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3922 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3923
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3924 return NGX_OK;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3925 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3926
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3927
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3928 static ngx_int_t
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3929 ngx_http_v2_filter_request_body(ngx_http_request_t *r)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3930 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3931 ngx_buf_t *b, *buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3932 ngx_int_t rc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3933 ngx_chain_t *cl;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3934 ngx_http_request_body_t *rb;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3935 ngx_http_core_loc_conf_t *clcf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3936
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3937 rb = r->request_body;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3938 buf = rb->buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3939
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3940 if (buf->pos == buf->last && rb->rest) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3941 cl = NULL;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3942 goto update;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3943 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3944
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3945 cl = ngx_chain_get_free_buf(r->pool, &rb->free);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3946 if (cl == NULL) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3947 return NGX_HTTP_INTERNAL_SERVER_ERROR;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3948 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3949
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3950 b = cl->buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3951
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3952 ngx_memzero(b, sizeof(ngx_buf_t));
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3953
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3954 if (buf->pos != buf->last) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3955 r->request_length += buf->last - buf->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3956 rb->received += buf->last - buf->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3957
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3958 if (r->headers_in.content_length_n != -1) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3959 if (rb->received > r->headers_in.content_length_n) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3960 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3961 "client intended to send body data "
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3962 "larger than declared");
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3963
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3964 return NGX_HTTP_BAD_REQUEST;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3965 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3966
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3967 } else {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3968 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3969
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3970 if (clcf->client_max_body_size
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3971 && rb->received > clcf->client_max_body_size)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3972 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3973 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3974 "client intended to send too large chunked body: "
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3975 "%O bytes", rb->received);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3976
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3977 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3978 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3979 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3980
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3981 b->temporary = 1;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3982 b->pos = buf->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3983 b->last = buf->last;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3984 b->start = b->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3985 b->end = b->last;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3986
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3987 buf->pos = buf->last;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3988 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3989
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3990 if (!rb->rest) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3991 if (r->headers_in.content_length_n != -1
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3992 && r->headers_in.content_length_n != rb->received)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3993 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3994 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3995 "client prematurely closed stream: "
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3996 "only %O out of %O bytes of request body received",
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3997 rb->received, r->headers_in.content_length_n);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3998
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3999 return NGX_HTTP_BAD_REQUEST;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4000 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4001
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4002 b->last_buf = 1;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4003 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4004
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4005 b->tag = (ngx_buf_tag_t) &ngx_http_v2_filter_request_body;
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4006 b->flush = r->request_body_no_buffering;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4007
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4008 update:
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4009
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4010 rc = ngx_http_top_request_body_filter(r, cl);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4011
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4012 ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &cl,
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4013 (ngx_buf_tag_t) &ngx_http_v2_filter_request_body);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4014
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4015 return rc;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4016 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4017
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4018
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4019 static void
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4020 ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r)
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4021 {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4022 ngx_connection_t *fc;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4023
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4024 fc = r->connection;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4025
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4026 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4027 "http2 read client request body handler");
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4028
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4029 if (fc->read->timedout) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4030 ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out");
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4031
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4032 fc->timedout = 1;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4033 r->stream->skip_data = 1;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4034
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4035 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4036 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4037 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4038
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4039 if (fc->error) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4040 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4041 "client prematurely closed stream");
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4042
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4043 r->stream->skip_data = 1;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4044
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4045 ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4046 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4047 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4048 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4049
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4050
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4051 ngx_int_t
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4052 ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r)
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4053 {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4054 size_t window;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4055 ngx_buf_t *buf;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4056 ngx_int_t rc;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4057 ngx_connection_t *fc;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4058 ngx_http_v2_stream_t *stream;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4059 ngx_http_v2_connection_t *h2c;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4060 ngx_http_core_loc_conf_t *clcf;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4061
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4062 stream = r->stream;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4063 fc = r->connection;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4064
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4065 if (fc->read->timedout) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4066 if (stream->recv_window) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4067 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4068 fc->timedout = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4069
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4070 return NGX_HTTP_REQUEST_TIME_OUT;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4071 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4072
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4073 fc->read->timedout = 0;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4074 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4075
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4076 if (fc->error) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4077 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4078 return NGX_HTTP_BAD_REQUEST;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4079 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4080
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4081 rc = ngx_http_v2_filter_request_body(r);
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4082
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4083 if (rc != NGX_OK) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4084 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4085 return rc;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4086 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4087
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4088 if (!r->request_body->rest) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4089 return NGX_OK;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4090 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4091
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4092 if (r->request_body->busy != NULL) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4093 return NGX_AGAIN;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4094 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4095
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4096 buf = r->request_body->buf;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4097
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4098 buf->pos = buf->start;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4099 buf->last = buf->start;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4100
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4101 window = buf->end - buf->start;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4102 h2c = stream->connection;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4103
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4104 if (h2c->state.stream == stream) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4105 window -= h2c->state.length;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4106 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4107
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4108 if (window <= stream->recv_window) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4109 if (window < stream->recv_window) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4110 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4111 "http2 negative window update");
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4112 stream->skip_data = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4113 return NGX_HTTP_INTERNAL_SERVER_ERROR;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4114 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4115
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4116 return NGX_AGAIN;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4117 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4118
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4119 if (ngx_http_v2_send_window_update(h2c, stream->node->id,
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4120 window - stream->recv_window)
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4121 == NGX_ERROR)
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4122 {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4123 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4124 return NGX_HTTP_INTERNAL_SERVER_ERROR;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4125 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4126
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4127 if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4128 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4129 return NGX_HTTP_INTERNAL_SERVER_ERROR;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4130 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4131
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4132 if (stream->recv_window == 0) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4133 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4134 ngx_add_timer(fc->read, clcf->client_body_timeout);
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4135 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4136
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4137 stream->recv_window = window;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4138
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4139 return NGX_AGAIN;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4140 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4141
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4142
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4143 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4144 ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4145 ngx_http_v2_stream_t *stream, ngx_uint_t status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4146 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4147 ngx_event_t *rev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4148 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4149
6588
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4150 if (stream->rst_sent) {
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4151 return NGX_OK;
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4152 }
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4153
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4154 if (ngx_http_v2_send_rst_stream(h2c, stream->node->id, status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4155 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4156 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4157 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4158 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4159
6495
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4160 stream->rst_sent = 1;
6588
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4161 stream->skip_data = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4162
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4163 fc = stream->request->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4164 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4165
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4166 rev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4167 rev->handler(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4168
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4169 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4170 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4171
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4172
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4173 void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4174 ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4175 {
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4176 ngx_pool_t *pool;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4177 ngx_uint_t push;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4178 ngx_event_t *ev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4179 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4180 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4181 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4182
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4183 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4184 node = stream->node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4185
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4186 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4187 "http2 close stream %ui, queued %ui, "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4188 "processing %ui, pushing %ui",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4189 node->id, stream->queued, h2c->processing, h2c->pushing);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4190
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4191 fc = stream->request->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4192
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4193 if (stream->queued) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4194 fc->write->handler = ngx_http_v2_close_stream_handler;
6590
d375f4210e41 HTTP/2: fixed the "http request count is zero" alert.
Valentin Bartenev <vbart@nginx.com>
parents: 6589
diff changeset
4195 fc->read->handler = ngx_http_empty_handler;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4196 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4197 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4198
6495
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4199 if (!stream->rst_sent && !h2c->connection->error) {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4200
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4201 if (!stream->out_closed) {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4202 if (ngx_http_v2_send_rst_stream(h2c, node->id,
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4203 fc->timedout ? NGX_HTTP_V2_PROTOCOL_ERROR
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4204 : NGX_HTTP_V2_INTERNAL_ERROR)
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4205 != NGX_OK)
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4206 {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4207 h2c->connection->error = 1;
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4208 }
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4209
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4210 } else if (!stream->in_closed) {
6515
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4211 #if 0
6495
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4212 if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4213 != NGX_OK)
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4214 {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4215 h2c->connection->error = 1;
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4216 }
6515
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4217 #else
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4218 /*
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4219 * At the time of writing at least the latest versions of Chrome
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4220 * do not properly handle RST_STREAM with NO_ERROR status.
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4221 *
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4222 * See: https://bugs.chromium.org/p/chromium/issues/detail?id=603182
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4223 *
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4224 * As a workaround, the stream window is maximized before closing
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4225 * the stream. This allows a client to send up to 2 GB of data
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4226 * before getting blocked on flow control.
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4227 */
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4228
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4229 if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4230 && ngx_http_v2_send_window_update(h2c, node->id,
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4231 NGX_HTTP_V2_MAX_WINDOW
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4232 - stream->recv_window)
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4233 != NGX_OK)
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4234 {
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4235 h2c->connection->error = 1;
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4236 }
8df664ebe037 HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6514
diff changeset
4237 #endif
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4238 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4239 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4240
6410
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4241 if (h2c->state.stream == stream) {
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4242 h2c->state.stream = NULL;
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4243 }
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4244
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4245 push = stream->node->id % 2 == 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4246
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4247 node->stream = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4248
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4249 ngx_queue_insert_tail(&h2c->closed, &node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4250 h2c->closed_nodes++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4251
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4252 /*
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4253 * This pool keeps decoded request headers which can be used by log phase
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4254 * handlers in ngx_http_free_request().
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4255 *
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4256 * The pointer is stored into local variable because the stream object
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4257 * will be destroyed after a call to ngx_http_free_request().
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4258 */
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4259 pool = stream->pool;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4260
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4261 ngx_http_free_request(stream->request, rc);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4262
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4263 if (pool != h2c->state.pool) {
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4264 ngx_destroy_pool(pool);
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4265
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4266 } else {
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4267 /* pool will be destroyed when the complete header is parsed */
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4268 h2c->state.keep_pool = 0;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4269 }
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4270
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4271 ev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4272
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4273 if (ev->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4274 ngx_del_timer(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4275 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4276
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4277 if (ev->posted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4278 ngx_delete_posted_event(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4279 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4280
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4281 ev = fc->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4282
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4283 if (ev->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4284 ngx_del_timer(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4285 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4286
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4287 if (ev->posted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4288 ngx_delete_posted_event(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4289 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4290
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4291 fc->data = h2c->free_fake_connections;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4292 h2c->free_fake_connections = fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4293
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4294 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4295 h2c->pushing--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4296
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4297 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4298 h2c->processing--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4299 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4300
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4301 if (h2c->processing || h2c->pushing || h2c->blocked) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4302 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4303 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4304
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4305 ev = h2c->connection->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4306
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4307 ev->handler = ngx_http_v2_handle_connection_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4308 ngx_post_event(ev, &ngx_posted_events);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4309 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4310
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4311
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4312 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4313 ngx_http_v2_close_stream_handler(ngx_event_t *ev)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4314 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4315 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4316 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4317
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4318 fc = ev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4319 r = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4320
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4321 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4322 "http2 close stream handler");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4323
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4324 if (ev->timedout) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4325 ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out");
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4326
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4327 fc->timedout = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4328
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4329 ngx_http_v2_close_stream(r->stream, NGX_HTTP_REQUEST_TIME_OUT);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4330 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4331 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4332
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4333 ngx_http_v2_close_stream(r->stream, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4334 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4335
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4336
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4337 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4338 ngx_http_v2_handle_connection_handler(ngx_event_t *rev)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4339 {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4340 ngx_connection_t *c;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4341 ngx_http_v2_connection_t *h2c;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4342
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4343 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4344 "http2 handle connection handler");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4345
6957
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4346 c = rev->data;
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4347 h2c = c->data;
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4348
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4349 if (c->error) {
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4350 ngx_http_v2_finalize_connection(h2c, 0);
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4351 return;
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4352 }
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4353
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4354 rev->handler = ngx_http_v2_read_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4355
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4356 if (rev->ready) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4357 ngx_http_v2_read_handler(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4358 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4359 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4360
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4361 if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4362 ngx_http_v2_finalize_connection(h2c, 0);
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4363 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4364 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4365
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4366 ngx_http_v2_handle_connection(c->data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4367 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4368
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4369
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4370 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4371 ngx_http_v2_idle_handler(ngx_event_t *rev)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4372 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4373 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4374 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4375 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4376
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4377 c = rev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4378 h2c = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4379
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4380 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 idle handler");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4381
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4382 if (rev->timedout || c->close) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4383 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4384 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4385 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4386
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4387 #if (NGX_HAVE_KQUEUE)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4388
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4389 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4390 if (rev->pending_eof) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4391 c->log->handler = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4392 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4393 "kevent() reported that client %V closed "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4394 "idle connection", &c->addr_text);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4395 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4396 if (c->ssl) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4397 c->ssl->no_send_shutdown = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4398 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4399 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4400 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4401 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4402 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4403 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4404
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4405 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4406
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4407 c->destroyed = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4408 ngx_reusable_connection(c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4409
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4410 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4411 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4412
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4413 h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4414 if (h2c->pool == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4415 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4416 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4417 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4418
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4419 c->write->handler = ngx_http_v2_write_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4420
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4421 rev->handler = ngx_http_v2_read_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4422 ngx_http_v2_read_handler(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4423 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4424
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4425
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4426 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4427 ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4428 ngx_uint_t status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4429 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4430 ngx_uint_t i, size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4431 ngx_event_t *ev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4432 ngx_connection_t *c, *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4433 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4434 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4435 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4436 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4437
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4438 c = h2c->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4439
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4440 h2c->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4441
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
4442 if (!c->error && !h2c->goaway) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
4443 if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
4444 (void) ngx_http_v2_send_output_queue(h2c);
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
4445 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4446 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4447
6495
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4448 c->error = 1;
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4449
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4450 if (!h2c->processing && !h2c->pushing) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4451 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4452 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4453 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4454
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4455 c->read->handler = ngx_http_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4456 c->write->handler = ngx_http_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4457
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4458 h2c->last_out = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4459
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4460 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4461 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4462
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4463 size = ngx_http_v2_index_size(h2scf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4464
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4465 for (i = 0; i < size; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4466
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4467 for (node = h2c->streams_index[i]; node; node = node->index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4468 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4469
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4470 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4471 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4472 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4473
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6805
diff changeset
4474 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4475
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4476 r = stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4477 fc = r->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4478
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4479 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4480
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4481 if (stream->queued) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4482 stream->queued = 0;
6956
9b5f31fdb850 HTTP/2: fixed stream finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6955
diff changeset
4483
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4484 ev = fc->write;
6956
9b5f31fdb850 HTTP/2: fixed stream finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6955
diff changeset
4485 ev->active = 0;
9b5f31fdb850 HTTP/2: fixed stream finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6955
diff changeset
4486 ev->ready = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4487
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4488 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4489 ev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4490 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4491
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4492 ev->eof = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4493 ev->handler(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4494 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4495 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4496
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4497 h2c->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4498
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4499 if (h2c->processing || h2c->pushing) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4500 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4501 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4502
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4503 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4504 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4505
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4506
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4507 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4508 ngx_http_v2_adjust_windows(ngx_http_v2_connection_t *h2c, ssize_t delta)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4509 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4510 ngx_uint_t i, size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4511 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4512 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4513 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4514 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4515
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4516 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4517 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4518
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4519 size = ngx_http_v2_index_size(h2scf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4520
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4521 for (i = 0; i < size; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4522
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4523 for (node = h2c->streams_index[i]; node; node = node->index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4524 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4525
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4526 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4527 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4528 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4529
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4530 if (delta > 0
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4531 && stream->send_window
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4532 > (ssize_t) (NGX_HTTP_V2_MAX_WINDOW - delta))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4533 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4534 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4535 NGX_HTTP_V2_FLOW_CTRL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4536 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4537 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4538 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4539 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4540
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4541 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4542 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4543
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4544 stream->send_window += delta;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4545
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4546 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
4547 "http2:%ui adjusted window: %z",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4548 node->id, stream->send_window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4549
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4550 if (stream->send_window > 0 && stream->exhausted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4551 stream->exhausted = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4552
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4553 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4554
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4555 wev->active = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4556 wev->ready = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4557
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4558 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4559 wev->handler(wev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4560 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4561 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4562 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4563 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4564
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4565 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4566 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4567
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4568
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4569 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4570 ngx_http_v2_set_dependency(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4571 ngx_http_v2_node_t *node, ngx_uint_t depend, ngx_uint_t exclusive)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4572 {
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4573 ngx_queue_t *children, *q;
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4574 ngx_http_v2_node_t *parent, *child, *next;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4575
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4576 parent = depend ? ngx_http_v2_get_node_by_id(h2c, depend, 0) : NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4577
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4578 if (parent == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4579 parent = NGX_HTTP_V2_ROOT;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4580
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4581 if (depend != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4582 exclusive = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4583 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4584
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4585 node->rank = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4586 node->rel_weight = (1.0 / 256) * node->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4587
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4588 children = &h2c->dependencies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4589
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4590 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4591 if (node->parent != NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4592
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4593 for (next = parent->parent;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4594 next != NGX_HTTP_V2_ROOT && next->rank >= node->rank;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4595 next = next->parent)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4596 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4597 if (next != node) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4598 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4599 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4600
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4601 ngx_queue_remove(&parent->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4602 ngx_queue_insert_after(&node->queue, &parent->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4603
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4604 parent->parent = node->parent;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4605
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4606 if (node->parent == NGX_HTTP_V2_ROOT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4607 parent->rank = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4608 parent->rel_weight = (1.0 / 256) * parent->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4609
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4610 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4611 parent->rank = node->parent->rank + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4612 parent->rel_weight = (node->parent->rel_weight / 256)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4613 * parent->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4614 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4615
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4616 if (!exclusive) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4617 ngx_http_v2_node_children_update(parent);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4618 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4619
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4620 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4621 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4622 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4623
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4624 node->rank = parent->rank + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4625 node->rel_weight = (parent->rel_weight / 256) * node->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4626
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4627 if (parent->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4628 ngx_queue_remove(&parent->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4629 ngx_queue_insert_tail(&h2c->closed, &parent->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4630 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4631
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4632 children = &parent->children;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4633 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4634
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4635 if (exclusive) {
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4636 for (q = ngx_queue_head(children);
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4637 q != ngx_queue_sentinel(children);
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4638 q = ngx_queue_next(q))
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4639 {
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4640 child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4641 child->parent = node;
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4642 }
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4643
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4644 ngx_queue_add(&node->children, children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4645 ngx_queue_init(children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4646 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4647
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4648 if (node->parent != NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4649 ngx_queue_remove(&node->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4650 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4651
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4652 ngx_queue_insert_tail(children, &node->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4653
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4654 node->parent = parent;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4655
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4656 ngx_http_v2_node_children_update(node);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4657 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4658
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4659
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4660 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4661 ngx_http_v2_node_children_update(ngx_http_v2_node_t *node)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4662 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4663 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4664 ngx_http_v2_node_t *child;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4665
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4666 for (q = ngx_queue_head(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4667 q != ngx_queue_sentinel(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4668 q = ngx_queue_next(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4669 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4670 child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4671
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4672 child->rank = node->rank + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4673 child->rel_weight = (node->rel_weight / 256) * child->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4674
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4675 ngx_http_v2_node_children_update(child);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4676 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4677 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4678
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4679
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4680 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4681 ngx_http_v2_pool_cleanup(void *data)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4682 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4683 ngx_http_v2_connection_t *h2c = data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4684
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4685 if (h2c->state.pool) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4686 ngx_destroy_pool(h2c->state.pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4687 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4688
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4689 if (h2c->pool) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4690 ngx_destroy_pool(h2c->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4691 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4692 }