annotate src/http/v2/ngx_http_v2.c @ 7703:da5e3f5b1673

HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR. Prodded by Xu Yang.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 02 Sep 2020 23:13:36 +0300
parents d57f15922ca3
children 097f578a4a8f
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
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
14 typedef struct {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
15 ngx_str_t name;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
16 ngx_uint_t offset;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
17 ngx_uint_t hash;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
18 ngx_http_header_t *hh;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
19 } ngx_http_v2_parse_header_t;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
20
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
21
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
22 /* errors */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
23 #define NGX_HTTP_V2_NO_ERROR 0x0
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
24 #define NGX_HTTP_V2_PROTOCOL_ERROR 0x1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
25 #define NGX_HTTP_V2_INTERNAL_ERROR 0x2
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
26 #define NGX_HTTP_V2_FLOW_CTRL_ERROR 0x3
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
27 #define NGX_HTTP_V2_SETTINGS_TIMEOUT 0x4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
28 #define NGX_HTTP_V2_STREAM_CLOSED 0x5
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
29 #define NGX_HTTP_V2_SIZE_ERROR 0x6
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
30 #define NGX_HTTP_V2_REFUSED_STREAM 0x7
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
31 #define NGX_HTTP_V2_CANCEL 0x8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
32 #define NGX_HTTP_V2_COMP_ERROR 0x9
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
33 #define NGX_HTTP_V2_CONNECT_ERROR 0xa
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
34 #define NGX_HTTP_V2_ENHANCE_YOUR_CALM 0xb
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
35 #define NGX_HTTP_V2_INADEQUATE_SECURITY 0xc
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
36 #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
37
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
38 /* frame sizes */
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
39 #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
40 #define NGX_HTTP_V2_RST_STREAM_SIZE 4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
41 #define NGX_HTTP_V2_PRIORITY_SIZE 5
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
42 #define NGX_HTTP_V2_PING_SIZE 8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
43 #define NGX_HTTP_V2_GOAWAY_SIZE 8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
44 #define NGX_HTTP_V2_WINDOW_UPDATE_SIZE 4
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
45
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
46 #define NGX_HTTP_V2_SETTINGS_PARAM_SIZE 6
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
47
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
48 /* settings fields */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
49 #define NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING 0x1
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
50 #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
51 #define NGX_HTTP_V2_MAX_STREAMS_SETTING 0x3
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
52 #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
53 #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
54
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
55 #define NGX_HTTP_V2_FRAME_BUFFER_SIZE 24
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
56
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
57 #define NGX_HTTP_V2_ROOT (void *) -1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
58
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
59
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
60 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
61 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
62 static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
63 static void ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
64 static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
65
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
66 static 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
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_preface(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_preface_end(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_head(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_data(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_read_data(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_headers(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_header_block(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_field_len(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_field_huff(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);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
86 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
87 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
88 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
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_process_header(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_header_complete(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);
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
94 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
95 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
96 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
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_rst_stream(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_settings(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_settings_params(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_push_promise(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_ping(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_goaway(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_window_update(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_continuation(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);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
114 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
115 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
116 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
117 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
118 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
119 u_char *pos, u_char *end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
120 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
121 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
122 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
123 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
124 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
125 ngx_uint_t err);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
126
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
127 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
128 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
129
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
130 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
131 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
132 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
133 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
134 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
135 ngx_http_v2_connection_t *h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
136 #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
137 #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
138
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
139 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
140 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
141 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
142 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
143 ngx_uint_t sid, size_t window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
144 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
145 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
146 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
147 ngx_uint_t status);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
148
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
149 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
150 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
151 u_char flags, ngx_uint_t sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
152 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
153 ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
154
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
155 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
156 ngx_http_v2_header_t *header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
157 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
158 ngx_http_v2_header_t *header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
159 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
160 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
161 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
162 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
163 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
164 ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
165 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
166 ngx_str_t *value);
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
167 static ngx_int_t ngx_http_v2_parse_header(ngx_http_request_t *r,
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
168 ngx_http_v2_parse_header_t *header, ngx_str_t *value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
169 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
170 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
171 ngx_http_v2_header_t *header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
172 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
173 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
174 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
175 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
176 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
177 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
178 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
179
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
180 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
181 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
182 static void ngx_http_v2_close_stream_handler(ngx_event_t *ev);
7611
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
183 static void ngx_http_v2_retry_close_stream_handler(ngx_event_t *ev);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
184 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
185 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
186 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
187 ngx_uint_t status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
188
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
189 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
190 ssize_t delta);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
191 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
192 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
193 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
194
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
195 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
196
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
197
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
198 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
199 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
200 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
201 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
202 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
203 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
204 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
205 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
206 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
207 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
208 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
209 };
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
210
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
211 #define NGX_HTTP_V2_FRAME_STATES \
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
212 (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
213
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
214
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
215 static ngx_http_v2_parse_header_t ngx_http_v2_parse_headers[] = {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
216 { ngx_string("host"),
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
217 offsetof(ngx_http_headers_in_t, host), 0, NULL },
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
218
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
219 { ngx_string("accept-encoding"),
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
220 offsetof(ngx_http_headers_in_t, accept_encoding), 0, NULL },
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
221
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
222 { ngx_string("accept-language"),
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
223 offsetof(ngx_http_headers_in_t, accept_language), 0, NULL },
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
224
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
225 { ngx_string("user-agent"),
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
226 offsetof(ngx_http_headers_in_t, user_agent), 0, NULL },
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
227
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
228 { ngx_null_string, 0, 0, NULL }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
229 };
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
230
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
231
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
232 void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
233 ngx_http_v2_init(ngx_event_t *rev)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
234 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
235 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
236 ngx_pool_cleanup_t *cln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
237 ngx_http_connection_t *hc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
238 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
239 ngx_http_v2_main_conf_t *h2mcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
240 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
241
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
242 c = rev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
243 hc = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
244
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
245 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
246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
247 c->log->action = "processing HTTP/2 connection";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
248
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
249 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
250
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
251 if (h2mcf->recv_buffer == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
252 h2mcf->recv_buffer = ngx_palloc(ngx_cycle->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
253 h2mcf->recv_buffer_size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
254 if (h2mcf->recv_buffer == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
255 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
256 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
257 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
260 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
261 if (h2c == 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 h2c->connection = c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
267 h2c->http_connection = hc;
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->send_window = NGX_HTTP_V2_DEFAULT_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
270 h2c->recv_window = NGX_HTTP_V2_MAX_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
271
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
272 h2c->init_window = NGX_HTTP_V2_DEFAULT_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
273
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
274 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
275
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
276 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
277
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
278 h2c->concurrent_pushes = h2scf->concurrent_pushes;
7549
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
279 h2c->priority_limit = h2scf->concurrent_streams;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
280
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
281 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
282 if (h2c->pool == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
283 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
284 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
285 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
286
6374
f598de1bfcd4 HTTP/2: fixed excessive memory allocation for pool cleanup.
Valentin Bartenev <vbart@nginx.com>
parents: 6312
diff changeset
287 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
288 if (cln == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
289 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
290 return;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
293 cln->handler = ngx_http_v2_pool_cleanup;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
294 cln->data = h2c;
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 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
297 * sizeof(ngx_http_v2_node_t *));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
298 if (h2c->streams_index == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
299 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
300 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
301 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
302
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
303 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
304 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
305 return;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
308 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
309 - NGX_HTTP_V2_DEFAULT_WINDOW)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
310 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
311 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
312 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
313 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
314 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
315
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
316 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
317 : ngx_http_v2_state_preface;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
318
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
319 ngx_queue_init(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
320 ngx_queue_init(&h2c->dependencies);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
321 ngx_queue_init(&h2c->closed);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
322
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
323 c->data = h2c;
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 rev->handler = ngx_http_v2_read_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
326 c->write->handler = ngx_http_v2_write_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
327
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
328 c->idle = 1;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
329
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
330 ngx_http_v2_read_handler(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
331 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
332
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
333
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
334 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
335 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
336 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
337 u_char *p, *end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
338 size_t available;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
339 ssize_t n;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
340 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
341 ngx_http_v2_main_conf_t *h2mcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
342 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
343
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
344 c = rev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
345 h2c = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
346
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
347 if (rev->timedout) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
348 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
349 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
350 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
351 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
352
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
353 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
354
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
355 h2c->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
356
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
357 if (c->close) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
358 c->close = 0;
6783
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
359
7571
ab5cac9d3f00 HTTP/2: fixed worker_shutdown_timeout.
Ruslan Ermilov <ru@nginx.com>
parents: 7570
diff changeset
360 if (c->error) {
ab5cac9d3f00 HTTP/2: fixed worker_shutdown_timeout.
Ruslan Ermilov <ru@nginx.com>
parents: 7570
diff changeset
361 ngx_http_v2_finalize_connection(h2c, 0);
ab5cac9d3f00 HTTP/2: fixed worker_shutdown_timeout.
Ruslan Ermilov <ru@nginx.com>
parents: 7570
diff changeset
362 return;
ab5cac9d3f00 HTTP/2: fixed worker_shutdown_timeout.
Ruslan Ermilov <ru@nginx.com>
parents: 7570
diff changeset
363 }
ab5cac9d3f00 HTTP/2: fixed worker_shutdown_timeout.
Ruslan Ermilov <ru@nginx.com>
parents: 7570
diff changeset
364
6783
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
365 if (!h2c->goaway) {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
366 h2c->goaway = 1;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
367
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
368 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
369 == NGX_ERROR)
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
370 {
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
371 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
372 return;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
373 }
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
374
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
375 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
376 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
377 return;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
378 }
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
379 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
380
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
381 h2c->blocked = 0;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
382
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
383 return;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
384 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
385
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
386 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
387 ngx_http_v2_module);
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 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
390
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
391 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
392 p = h2mcf->recv_buffer;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
393
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
394 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
395 end = p + h2c->state.buffer_used;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
396
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
397 n = c->recv(c, end, available);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
398
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
399 if (n == NGX_AGAIN) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
400 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
401 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
402
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
403 if (n == 0
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
404 && (h2c->state.incomplete || h2c->processing || h2c->pushing))
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
405 {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
406 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
407 "client prematurely closed connection");
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 if (n == 0 || n == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
411 c->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
412 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
413 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
414 }
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 end += n;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
417
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
418 h2c->state.buffer_used = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
419 h2c->state.incomplete = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
420
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
421 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
422 p = h2c->state.handler(h2c, p, end);
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 if (p == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
425 return;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
428 } while (p != end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
429
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
430 h2c->total_bytes += n;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
431
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
432 if (h2c->total_bytes / 8 > h2c->payload_bytes + 1048576) {
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
433 ngx_log_error(NGX_LOG_INFO, c->log, 0, "http2 flood detected");
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
434 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
435 return;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
436 }
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
437
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
438 } while (rev->ready);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
439
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
440 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
441 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
442 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
443 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
444
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
445 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
446 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
447 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
448 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
449
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
450 h2c->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
451
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
452 if (h2c->processing || h2c->pushing) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
453 if (rev->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
454 ngx_del_timer(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
455 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
456
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
457 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
458 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
459
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
460 ngx_http_v2_handle_connection(h2c);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
464 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
465 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
466 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
467 ngx_int_t rc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
468 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
469 ngx_http_v2_connection_t *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 c = wev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
472 h2c = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
473
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
474 if (wev->timedout) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
475 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
476 "http2 write event timed out");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
477 c->error = 1;
7695
d57f15922ca3 HTTP/2: fixed c->timedout flag on timed out connections.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7673
diff changeset
478 c->timedout = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
479 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
480 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
481 }
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 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
484
6639
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
485 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
486
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
487 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
488 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
489 }
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
490
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
491 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
492 return;
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
493 }
82efcedb310b HTTP/2: avoid sending output queue if there's nothing to send.
Valentin Bartenev <vbart@nginx.com>
parents: 6636
diff changeset
494
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
495 h2c->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
496
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
497 rc = ngx_http_v2_send_output_queue(h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
498
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
499 if (rc == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
500 ngx_http_v2_finalize_connection(h2c, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
501 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
502 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
503
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
504 h2c->blocked = 0;
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 if (rc == NGX_AGAIN) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
507 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
508 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
509
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
510 ngx_http_v2_handle_connection(h2c);
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
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 ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
515 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
516 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
517 int tcp_nodelay;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
518 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
519 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
520 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
521 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
522 ngx_http_core_loc_conf_t *clcf;
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 c = h2c->connection;
7570
d6cf51af8a3d HTTP/2: fixed possible alert about left open socket on shutdown.
Ruslan Ermilov <ru@nginx.com>
parents: 7569
diff changeset
525 wev = c->write;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
526
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
527 if (c->error) {
7570
d6cf51af8a3d HTTP/2: fixed possible alert about left open socket on shutdown.
Ruslan Ermilov <ru@nginx.com>
parents: 7569
diff changeset
528 goto error;
d6cf51af8a3d HTTP/2: fixed possible alert about left open socket on shutdown.
Ruslan Ermilov <ru@nginx.com>
parents: 7569
diff changeset
529 }
6246
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 if (!wev->ready) {
6641
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
532 return NGX_AGAIN;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
535 cl = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
536 out = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
537
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
538 for (frame = h2c->last_out; frame; frame = fn) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
539 frame->last->next = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
540 cl = frame->first;
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 fn = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
543 frame->next = out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
544 out = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
545
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
546 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
547 "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
548 out, out->stream ? out->stream->node->id : 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
549 out->blocked, out->length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
550 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
551
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
552 cl = c->send_chain(c, cl, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
553
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
554 if (cl == NGX_CHAIN_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
555 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
556 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
557
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
558 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
559 ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
560
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
561 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
562 goto error;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
565 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
566 if (ngx_tcp_push(c->fd) == -1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
567 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
568 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
569 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
570
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
571 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
572 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
573
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
574 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
575 tcp_nodelay = 1;
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
7007
ed1101bbf19f Introduced ngx_tcp_nodelay().
Ruslan Ermilov <ru@nginx.com>
parents: 6989
diff changeset
578 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
579 goto error;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
582 for ( /* void */ ; out; out = fn) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
583 fn = out->next;
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 if (out->handler(h2c, out) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
586 out->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
587 break;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
590 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
591 "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
592 out, out->stream ? out->stream->node->id : 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
593 out->blocked, out->length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
594 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
595
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
596 frame = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
597
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
598 for ( /* void */ ; out; out = fn) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
599 fn = out->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
600 out->next = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
601 frame = out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
602 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
603
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
604 h2c->last_out = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
605
6641
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
606 if (!wev->ready) {
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
607 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
608 return NGX_AGAIN;
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
609 }
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
610
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
611 if (wev->timer_set) {
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
612 ngx_del_timer(wev);
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
613 }
b5d1c17181ca HTTP/2: refactored ngx_http_v2_send_output_queue().
Valentin Bartenev <vbart@nginx.com>
parents: 6640
diff changeset
614
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
615 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
616
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
617 error:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
618
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
619 c->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
620
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
621 if (!h2c->blocked) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
622 ngx_post_event(wev, &ngx_posted_events);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
623 }
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 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
626 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
627
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
628
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
629 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
630 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
631 {
6642
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
632 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
633 ngx_connection_t *c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
634 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
635
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
636 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
637 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
638 }
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 c = h2c->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
641
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
642 if (c->error) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
643 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
644 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
645 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
646
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
647 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
648 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
649
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
650 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
651
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
652 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
653
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
654 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
655 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
656 return;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
657 }
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
658
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
659 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
660 return;
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
661 }
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
662
72282dd5884e HTTP/2: flushing of the SSL buffer in transition to the idle state.
Valentin Bartenev <vbart@nginx.com>
parents: 6641
diff changeset
663 /* rc == NGX_OK */
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
664 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
665
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
666 if (h2c->goaway) {
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
667 ngx_http_v2_lingering_close(h2c);
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
668 return;
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
669 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
670
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
671 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
672 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
673 if (h2c->state.incomplete) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
674 ngx_add_timer(c->read, h2scf->recv_timeout);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
675 return;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
678 ngx_destroy_pool(h2c->pool);
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 h2c->pool = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
681 h2c->free_frames = NULL;
7377
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
682 h2c->frames = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
683 h2c->free_fake_connections = NULL;
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 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
686 if (c->ssl) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
687 ngx_ssl_free_buffer(c);
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 #endif
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 c->destroyed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
692 ngx_reusable_connection(c, 1);
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 c->write->handler = ngx_http_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
695 c->read->handler = ngx_http_v2_idle_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
696
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
697 if (c->write->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
698 ngx_del_timer(c->write);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
701 ngx_add_timer(c->read, h2scf->idle_timeout);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
704
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
705 static void
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
706 ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c)
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
707 {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
708 ngx_event_t *rev, *wev;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
709 ngx_connection_t *c;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
710 ngx_http_core_loc_conf_t *clcf;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
711
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
712 c = h2c->connection;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
713
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
714 clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
715 ngx_http_core_module);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
716
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
717 if (clcf->lingering_close == NGX_HTTP_LINGERING_OFF) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
718 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
719 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
720 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
721
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
722 rev = c->read;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
723 rev->handler = ngx_http_v2_lingering_close_handler;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
724
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
725 h2c->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
726 ngx_add_timer(rev, clcf->lingering_timeout);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
727
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
728 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
729 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
730 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
731 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
732
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
733 wev = c->write;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
734 wev->handler = ngx_http_empty_handler;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
735
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
736 if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
737 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
738 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
739 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
740 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
741 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
742
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
743 if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
744 ngx_connection_error(c, ngx_socket_errno,
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
745 ngx_shutdown_socket_n " failed");
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
746 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
747 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
748 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
749
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
750 if (rev->ready) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
751 ngx_http_v2_lingering_close_handler(rev);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
752 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
753 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
754
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
755
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
756 static void
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
757 ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
758 {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
759 ssize_t n;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
760 ngx_msec_t timer;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
761 ngx_connection_t *c;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
762 ngx_http_core_loc_conf_t *clcf;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
763 ngx_http_v2_connection_t *h2c;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
764 u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
765
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
766 c = rev->data;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
767 h2c = c->data;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
768
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
769 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
770 "http2 lingering close handler");
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
771
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
772 if (rev->timedout) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
773 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
774 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
775 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
776
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
777 timer = (ngx_msec_t) h2c->lingering_time - (ngx_msec_t) ngx_time();
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
778 if ((ngx_msec_int_t) timer <= 0) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
779 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
780 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
781 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
782
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
783 do {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
784 n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
785
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
786 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %z", n);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
787
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
788 if (n == NGX_ERROR || n == 0) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
789 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
790 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
791 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
792
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
793 } while (rev->ready);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
794
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
795 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
796 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
797 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
798 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
799
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
800 clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
801 ngx_http_core_module);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
802 timer *= 1000;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
803
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
804 if (timer > clcf->lingering_timeout) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
805 timer = clcf->lingering_timeout;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
806 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
807
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
808 ngx_add_timer(rev, timer);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
809 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
810
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
811
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
812 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
813 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
814 u_char *end)
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 ngx_log_t *log;
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 log = h2c->connection->log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
819 log->action = "reading PROXY protocol";
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 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
822
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
823 log->action = "processing HTTP/2 connection";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
824
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
825 if (pos == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
826 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
827 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
828
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
829 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
830 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
831
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
834 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
835 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
836 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
837 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
838
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
839 if ((size_t) (end - pos) < sizeof(preface) - 1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
840 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
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 if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
7656
7114d21bc2b1 HTTP/2: invalid connection preface logging (ticket #1981).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7623
diff changeset
844 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
7114d21bc2b1 HTTP/2: invalid connection preface logging (ticket #1981).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7623
diff changeset
845 "invalid connection preface");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
846
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
847 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
848 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
849
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
850 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
851 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
852
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
853
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
854 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
855 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
856 u_char *end)
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 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
859
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
860 if ((size_t) (end - pos) < sizeof(preface) - 1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
861 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
862 ngx_http_v2_state_preface_end);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
863 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
864
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
865 if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
7656
7114d21bc2b1 HTTP/2: invalid connection preface logging (ticket #1981).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7623
diff changeset
866 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
7114d21bc2b1 HTTP/2: invalid connection preface logging (ticket #1981).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7623
diff changeset
867 "invalid connection preface");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
868
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
869 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
870 }
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 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
873 "http2 preface verified");
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 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
876 }
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
880 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
881 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
882 uint32_t head;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
883 ngx_uint_t type;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
884
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
885 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
886 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
887 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
888
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
889 head = ngx_http_v2_parse_uint32(pos);
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 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
892 h2c->state.flags = pos[4];
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 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
895
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
896 pos += NGX_HTTP_V2_FRAME_HEADER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
897
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
898 type = ngx_http_v2_parse_type(head);
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 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
901 "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
902 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
903
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
904 if (type >= NGX_HTTP_V2_FRAME_STATES) {
7225
e80930e5e422 HTTP/2: unknown frames now logged at info level.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7216
diff changeset
905 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
e80930e5e422 HTTP/2: unknown frames now logged at info level.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7216
diff changeset
906 "client sent frame with unknown type %ui", type);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
907 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
908 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
909
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
910 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
911 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
912
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
915 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
916 {
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
917 size_t size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
918 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
919 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
920
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
921 size = h2c->state.length;
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
922
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
923 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
924
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
925 if (h2c->state.length == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
926 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
927 "client sent padded DATA frame "
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
928 "with incorrect length: 0");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
929
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
930 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
931 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
932
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
933 if (end - pos == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
934 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
935 ngx_http_v2_state_data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
936 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
937
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
938 h2c->state.padding = *pos++;
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
939
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
940 if (h2c->state.padding >= size) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
941 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
942 "client sent padded DATA frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
943 "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
944 size, h2c->state.padding);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
945
6955
d38161da62cd HTTP/2: emit PROTOCOL_ERROR on padding errors.
Piotr Sikora <piotrsikora@google.com>
parents: 6954
diff changeset
946 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
947 NGX_HTTP_V2_PROTOCOL_ERROR);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
948 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
949
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
950 h2c->state.length -= 1 + h2c->state.padding;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
951 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
952
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
953 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
954 "http2 DATA frame");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
955
7703
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
956 if (h2c->state.sid == 0) {
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
957 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
958 "client sent DATA frame with incorrect identifier");
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
959
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
960 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
961 }
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
962
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
963 if (size > h2c->recv_window) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
964 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
965 "client violated connection flow control: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
966 "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
967 size, h2c->recv_window);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
968
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
969 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
970 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
971
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
972 h2c->recv_window -= size;
6246
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 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
975
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
976 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
977 - h2c->recv_window)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
978 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
979 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
980 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
981 NGX_HTTP_V2_INTERNAL_ERROR);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
984 h2c->recv_window = NGX_HTTP_V2_MAX_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
985 }
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 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
988
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
989 if (node == NULL || node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
990 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
991 "unknown http2 stream");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
992
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
993 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
994 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
995
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
996 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
997
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
998 if (size > stream->recv_window) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
999 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
1000 "client violated flow control for stream %ui: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1001 "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
1002 node->id, size, stream->recv_window);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1003
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1004 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1005 NGX_HTTP_V2_FLOW_CTRL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1006 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1007 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1008 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1009 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1010 }
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_state_skip_padded(h2c, pos, end);
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
6954
052305810ca4 HTTP/2: fix flow control with padded DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 6834
diff changeset
1015 stream->recv_window -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1016
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1017 if (stream->no_flow_control
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1018 && 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
1019 {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1020 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
1021 NGX_HTTP_V2_MAX_WINDOW
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1022 - stream->recv_window)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1023 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1024 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1025 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1026 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1027 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1028
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1029 stream->recv_window = NGX_HTTP_V2_MAX_WINDOW;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1030 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1031
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1032 if (stream->in_closed) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1033 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
1034 "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
1035 node->id);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1036
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1037 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1038 NGX_HTTP_V2_STREAM_CLOSED)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1039 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1040 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1041 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1042 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1043 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1044
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1045 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
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.stream = stream;
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 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
1051 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1052
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1053
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1054 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1055 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
1056 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1057 {
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1058 size_t size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1059 ngx_buf_t *buf;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1060 ngx_int_t rc;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1061 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
1062 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
1063 ngx_http_v2_srv_conf_t *h2scf;
6246
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 stream = h2c->state.stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1066
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1067 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1068 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
1069 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1070
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1071 if (stream->skip_data) {
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1072 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
1073 "skipping http2 DATA frame");
6246
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_state_skip_padded(h2c, pos, end);
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
7561
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1078 r = stream->request;
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1079
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1080 if (r->reading_body && !r->request_body_no_buffering) {
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1081 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1082 "skipping http2 DATA frame");
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1083
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1084 return ngx_http_v2_state_skip_padded(h2c, pos, end);
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1085 }
9f1f9d6e056a HTTP/2: discard remaining request body after redirect.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7549
diff changeset
1086
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1087 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1088
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1089 if (size >= h2c->state.length) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1090 size = h2c->state.length;
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
1091 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
1092 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1093
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
1094 h2c->payload_bytes += size;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
1095
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1096 if (r->request_body) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1097 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
1098
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1099 if (rc != NGX_OK) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1100 stream->skip_data = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1101 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
1102 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1103
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1104 } else if (size) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1105 buf = stream->preread;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1106
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1107 if (buf == NULL) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1108 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
1109
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1110 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
1111 if (buf == NULL) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1112 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
1113 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
1114 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1115
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1116 stream->preread = buf;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1117 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1118
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1119 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
1120 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
1121 "http2 preread buffer overflow");
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1122 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
1123 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
1124 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1125
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1126 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
1127 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1128
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1129 pos += size;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
1130 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1131
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1132 if (h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1133 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
1134 ngx_http_v2_state_read_data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1135 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1136
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1137 if (h2c->state.padding) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1138 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
1139 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1140
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1141 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
1142 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1143
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1144
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1145 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1146 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
1147 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1148 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1149 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1150 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
1151 ngx_uint_t status;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1152 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1153 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1154 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1155
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1156 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
1157 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
1158
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1159 size = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1160
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1161 if (padded) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1162 size++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1163 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1164
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1165 if (priority) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1166 size += sizeof(uint32_t) + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1167 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1168
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1169 if (h2c->state.length < size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1170 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
1171 "client sent HEADERS frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1172 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1173
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1174 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
1175 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1176
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1177 if (h2c->state.length == size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1178 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
1179 "client sent HEADERS frame with empty header block");
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 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
1182 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1183
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1184 if (h2c->goaway) {
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1185 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
1186 "skipping http2 HEADERS frame");
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1187 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
1188 }
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
1189
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1190 if ((size_t) (end - pos) < size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1191 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
1192 ngx_http_v2_state_headers);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1193 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1194
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1195 h2c->state.length -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1196
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1197 if (padded) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1198 h2c->state.padding = *pos++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1199
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1200 if (h2c->state.padding > h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1201 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
1202 "client sent padded HEADERS frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1203 "with incorrect length: %uz, padding: %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1204 h2c->state.length, h2c->state.padding);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1205
6955
d38161da62cd HTTP/2: emit PROTOCOL_ERROR on padding errors.
Piotr Sikora <piotrsikora@google.com>
parents: 6954
diff changeset
1206 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
1207 NGX_HTTP_V2_PROTOCOL_ERROR);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1208 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1209
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1210 h2c->state.length -= h2c->state.padding;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1211 }
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 depend = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1214 excl = 0;
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1215 weight = NGX_HTTP_V2_DEFAULT_WEIGHT;
6246
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 if (priority) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1218 dependency = ngx_http_v2_parse_uint32(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1219
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1220 depend = dependency & 0x7fffffff;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1221 excl = dependency >> 31;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1222 weight = pos[4] + 1;
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 pos += sizeof(uint32_t) + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1225 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1226
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1227 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
1228 "http2 HEADERS frame sid:%ui "
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1229 "depends on %ui excl:%ui weight:%ui",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1230 h2c->state.sid, depend, excl, weight);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1231
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1232 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
1233 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
1234 "client sent HEADERS frame with incorrect identifier "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1235 "%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
1236
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1237 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
1238 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1239
7564
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1240 if (depend == h2c->state.sid) {
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1241 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1242 "client sent HEADERS frame for stream %ui "
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1243 "with incorrect dependency", h2c->state.sid);
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1244
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1245 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1246 }
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1247
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1248 h2c->last_sid = h2c->state.sid;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1249
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1250 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
1251 if (h2c->state.pool == NULL) {
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1252 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
1253 }
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1254
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1255 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
1256 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1257
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1258 h2c->state.header_limit = h2scf->max_header_size;
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 (h2c->processing >= h2scf->concurrent_streams) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1261 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
1262 "concurrent streams exceeded %ui", h2c->processing);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1263
6513
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1264 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
1265 goto rst_stream;
6246
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
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1268 if (!h2c->settings_ack
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
1269 && !(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
1270 && 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
1271 {
6516
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1272 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
1273 "client sent stream with data "
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1274 "before settings were acknowledged");
ab16126a06a0 HTTP/2: write logs when refusing streams with data.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6515
diff changeset
1275
6514
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1276 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
1277 goto rst_stream;
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1278 }
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
1279
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1280 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
1281
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1282 if (node == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1283 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
1284 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1285
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1286 if (node->parent) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1287 ngx_queue_remove(&node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1288 h2c->closed_nodes--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1289 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1290
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
1291 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
1292 if (stream == NULL) {
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_INTERNAL_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
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1296 h2c->state.stream = stream;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1297
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1298 stream->pool = h2c->state.pool;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1299 h2c->state.keep_pool = 1;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1300
6375
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1301 stream->request->request_length = h2c->state.length;
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1302
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1303 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
1304 stream->node = node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1305
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1306 node->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1307
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1308 if (priority || node->parent == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1309 node->weight = weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1310 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
1311 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1312
6783
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1313 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
1314 h2c->goaway = 1;
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1315
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1316 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
1317 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
1318 NGX_HTTP_V2_INTERNAL_ERROR);
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1319 }
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1320 }
9027991e2f37 HTTP/2: limited maximum number of requests in connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6778
diff changeset
1321
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1322 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
1323
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1324 rst_stream:
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1325
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1326 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
1327 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
1328 }
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1329
80ba811112ed HTTP/2: deduplicated some code in ngx_http_v2_state_headers().
Valentin Bartenev <vbart@nginx.com>
parents: 6497
diff changeset
1330 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
1331 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1332
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1335 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
1336 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1337 {
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1338 u_char ch;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1339 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
1340 ngx_uint_t indexed, size_update, prefix;
6246
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 if (end - pos < 1) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1343 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
1344 ngx_http_v2_state_header_block);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1345 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1346
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1347 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
1348 && 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
1349 {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1350 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
1351 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
1352 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1353
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1354 size_update = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1355 indexed = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1356
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1357 ch = *pos;
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 if (ch >= (1 << 7)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1360 /* indexed header field */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1361 indexed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1362 prefix = ngx_http_v2_prefix(7);
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 } else if (ch >= (1 << 6)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1365 /* literal header field with incremental indexing */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1366 h2c->state.index = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1367 prefix = ngx_http_v2_prefix(6);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1368
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1369 } else if (ch >= (1 << 5)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1370 /* dynamic table size update */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1371 size_update = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1372 prefix = ngx_http_v2_prefix(5);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1373
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1374 } else if (ch >= (1 << 4)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1375 /* literal header field never indexed */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1376 prefix = ngx_http_v2_prefix(4);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1377
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1378 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1379 /* 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
1380 prefix = ngx_http_v2_prefix(4);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1381 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1382
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1383 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
1384
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1385 if (value < 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1386 if (value == NGX_AGAIN) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1387 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
1388 ngx_http_v2_state_header_block);
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1391 if (value == NGX_DECLINED) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1392 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
1393 "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
1394 size_update ? "size update" : "header index");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1395
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1396 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
1397 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1398
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1399 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
1400 "client sent header block with incorrect length");
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 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
1403 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1404
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1405 if (indexed) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1406 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
1407 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
1408 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1409
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1410 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
1411 }
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 if (size_update) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1414 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
1415 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
1416 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1417
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1418 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
1419 }
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 if (value == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1422 h2c->state.parse_name = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1423
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1424 } 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
1425 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
1426 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1427
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1428 h2c->state.parse_value = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1429
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1430 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
1431 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1432
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1433
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1434 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1435 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
1436 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1437 {
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1438 size_t alloc;
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1439 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
1440 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
1441 ngx_http_v2_srv_conf_t *h2scf;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1442
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1443 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
1444 && 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
1445 {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1446 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
1447 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
1448 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1449
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1450 if (h2c->state.length < 1) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1451 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
1452 "client sent header block with incorrect length");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1453
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1454 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
1455 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1456
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1457 if (end - pos < 1) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1458 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
1459 ngx_http_v2_state_field_len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1460 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1461
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1462 huff = *pos >> 7;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1463 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
1464
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1465 if (len < 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1466 if (len == NGX_AGAIN) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1467 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
1468 ngx_http_v2_state_field_len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1469 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1470
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1471 if (len == NGX_DECLINED) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1472 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
1473 "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
1474
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1475 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
1476 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1477
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1478 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
1479 "client sent header block with incorrect length");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1480
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1481 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
1482 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1483
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1484 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
1485 "http2 %s string, len:%i",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1486 huff ? "encoded" : "raw", len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1487
6285
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1488 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
1489 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
1490
1f26bf65b1bc HTTP/2: changed behavior of the "http2_max_field_size" directive.
Valentin Bartenev <vbart@nginx.com>
parents: 6284
diff changeset
1491 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
1492 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
1493 "client exceeded http2_max_field_size limit");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1494
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1495 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
1496 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1497
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1498 h2c->state.field_rest = len;
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 if (h2c->state.stream == NULL && !h2c->state.index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1501 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
1502 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1503
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1504 alloc = (huff ? len * 8 / 5 : len) + 1;
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 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
1507 if (h2c->state.field_start == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1508 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
1509 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1510
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1511 h2c->state.field_end = h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1512
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1513 if (huff) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1514 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
1515 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1516
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1517 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
1518 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1519
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1520
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1521 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1522 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
1523 u_char *end)
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 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1526
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1527 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1528
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1529 if (size > h2c->state.field_rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1530 size = h2c->state.field_rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1531 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1532
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1533 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
1534 size = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1535 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1536
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1537 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1538 h2c->state.field_rest -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1539
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1540 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
1541 &h2c->state.field_end,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1542 h2c->state.field_rest == 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1543 h2c->connection->log)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1544 != NGX_OK)
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 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
1547 "client sent invalid encoded header field");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1548
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1549 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
1550 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1551
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1552 pos += size;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1553
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1554 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
1555 *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
1556 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
1557 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1558
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1559 if (h2c->state.length) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1560 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
1561 ngx_http_v2_state_field_huff);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1562 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1563
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1564 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
1565 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
1566 "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
1567
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1568 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
1569 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1570
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1571 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
1572 ngx_http_v2_state_field_huff);
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1575
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1576 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1577 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
1578 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1579 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1580 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1581
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1582 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1583
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1584 if (size > h2c->state.field_rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1585 size = h2c->state.field_rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1586 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1587
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1588 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
1589 size = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1590 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1591
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1592 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1593 h2c->state.field_rest -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1594
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1595 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
1596
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1597 pos += size;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1598
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1599 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
1600 *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
1601 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
1602 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1603
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1604 if (h2c->state.length) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
1605 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
1606 ngx_http_v2_state_field_raw);
6246
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
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1609 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
1610 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
1611 "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
1612
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1613 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
1614 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1615
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1616 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
1617 ngx_http_v2_state_field_raw);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1618 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1619
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1620
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1621 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1622 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
1623 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1624 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1625 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1626
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1627 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1628
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1629 if (size > h2c->state.field_rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1630 size = h2c->state.field_rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1631 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1632
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1633 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
1634 size = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1635 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1636
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1637 h2c->state.length -= size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1638 h2c->state.field_rest -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1639
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1640 pos += size;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1641
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1642 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
1643 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
1644 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1645
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1646 if (h2c->state.length) {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1647 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
1648 ngx_http_v2_state_field_skip);
f5380c244cd7 HTTP/2: fixed HPACK header field parsing.
Valentin Bartenev <vbart@nginx.com>
parents: 6246
diff changeset
1649 }
f5380c244cd7 HTTP/2: fixed HPACK header field parsing.
Valentin Bartenev <vbart@nginx.com>
parents: 6246
diff changeset
1650
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1651 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
1652 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
1653 "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
1654
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1655 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
1656 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1657
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1658 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
1659 ngx_http_v2_state_field_skip);
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1662
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1663 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1664 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
1665 u_char *end)
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 size_t len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1668 ngx_int_t rc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1669 ngx_table_elt_t *h;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1670 ngx_http_header_t *hh;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1671 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1672 ngx_http_v2_header_t *header;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1673 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1674 ngx_http_core_main_conf_t *cmcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1675
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1676 static ngx_str_t cookie = ngx_string("cookie");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1677
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1678 header = &h2c->state.header;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1679
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1680 if (h2c->state.parse_name) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1681 h2c->state.parse_name = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1682
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1683 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
1684 header->name.data = h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1685
7547
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1686 if (header->name.len == 0) {
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1687 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1688 "client sent zero header name length");
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1689
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1690 return ngx_http_v2_connection_error(h2c,
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1691 NGX_HTTP_V2_PROTOCOL_ERROR);
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1692 }
4f4b83f00cf1 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7378
diff changeset
1693
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1694 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
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 if (h2c->state.parse_value) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1698 h2c->state.parse_value = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1699
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1700 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
1701 header->value.data = h2c->state.field_start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1702 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1703
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1704 len = header->name.len + header->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1705
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1706 if (len > h2c->state.header_limit) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1707 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
1708 "client exceeded http2_max_header_size limit");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1709
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1710 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
1711 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1712
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1713 h2c->state.header_limit -= len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1714
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1715 if (h2c->state.index) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1716 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
1717 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1718 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1719 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1720
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1721 h2c->state.index = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1722 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1723
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1724 if (h2c->state.stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1725 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
1726 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1727
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1728 r = h2c->state.stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1729
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1730 /* TODO Optimization: validate headers while parsing. */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1731 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
1732 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
1733 NGX_HTTP_V2_PROTOCOL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1734 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1735 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1736 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1737 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1738 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1739
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1740 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1741 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1742
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1743 if (header->name.data[0] == ':') {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1744 rc = ngx_http_v2_pseudo_header(r, header);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1745
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1746 if (rc == NGX_OK) {
7016
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1747 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
1748 "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
1749 &header->name, &header->value);
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1750
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1751 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
1752 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1753
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1754 if (rc == NGX_ABORT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1755 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1756 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1757
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1758 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
1759 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
1760 goto error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1761 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1762
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1763 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
1764 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1765
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1766 if (r->invalid_header) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1767 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
1768
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1769 if (cscf->ignore_invalid_headers) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1770 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
1771 "client sent invalid header: \"%V\"", &header->name);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1772
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1773 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
1774 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1775 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1776
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1777 if (header->name.len == cookie.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1778 && 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
1779 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1780 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
1781 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1782 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1783 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1784
7016
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1785 } else {
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1786 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
1787 if (h == NULL) {
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1788 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
1789 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
1790 }
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1791
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1792 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
1793 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
1794
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1795 /*
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1796 * TODO Optimization: precalculate hash
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1797 * 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
1798 */
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1799 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
1800
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1801 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
1802 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
1803
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1804 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
1805
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1806 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
1807
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1808 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
1809 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
1810
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1811 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
1812 goto error;
ab6ef3037840 HTTP/2: add debug logging of pseudo-headers and cookies.
Piotr Sikora <piotrsikora@google.com>
parents: 7007
diff changeset
1813 }
6246
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 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
1817 "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
1818 &header->name, &header->value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1819
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1820 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
1821
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1822 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 h2c->state.stream = NULL;
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_header_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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1830 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1831 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
1832 u_char *end)
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 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1835
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1836 if (h2c->state.length) {
7623
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1837 if (end - pos > 0) {
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1838 h2c->state.handler = ngx_http_v2_state_header_block;
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1839 return pos;
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1840 }
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1841
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1842 return ngx_http_v2_state_headers_save(h2c, pos, end,
72b792bb3885 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7618
diff changeset
1843 ngx_http_v2_state_header_block);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1844 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1845
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1846 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
1847 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
1848 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
1849 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1850
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1851 stream = h2c->state.stream;
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 if (stream) {
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1854 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
1855 }
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1856
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1857 if (!h2c->state.keep_pool) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1858 ngx_destroy_pool(h2c->state.pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1859 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1860
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1861 h2c->state.pool = NULL;
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
1862 h2c->state.keep_pool = 0;
6246
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.padding) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1865 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
1866 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1867
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1868 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
1869 }
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 static u_char *
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1873 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
1874 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
1875 {
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1876 u_char *p;
6376
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1877 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
1878 uint32_t head;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1879
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1880 len = h2c->state.length;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1881
6376
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1882 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
1883 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
1884
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1885 h2c->state.padding -= skip;
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1886
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1887 p = pos;
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1888 pos += skip;
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1889 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
1890 }
0e0e2e522fa2 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.
Valentin Bartenev <vbart@nginx.com>
parents: 6375
diff changeset
1891
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1892 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
1893 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
1894 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1895
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1896 p = pos + len;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1897
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1898 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
1899
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1900 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
1901 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
1902 "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
1903
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1904 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
1905 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1906
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1907 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
1908
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1909 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
1910 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
1911 "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
1912
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1913 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
1914 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1915
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1916 p = pos;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1917 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
1918
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1919 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
1920
6375
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1921 len = ngx_http_v2_parse_length(head);
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1922
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1923 h2c->state.length += len;
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1924
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1925 if (h2c->state.stream) {
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1926 h2c->state.stream->request->request_length += len;
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1927 }
e30c72b0dfda HTTP/2: fixed request length accounting.
Valentin Bartenev <vbart@nginx.com>
parents: 6374
diff changeset
1928
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1929 h2c->state.handler = handler;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1930 return pos;
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1931 }
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1932
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1933
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
1934 static u_char *
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1935 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
1936 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1937 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1938 ngx_uint_t depend, dependency, excl, weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1939 ngx_http_v2_node_t *node;
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 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
1942 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
1943 "client sent PRIORITY frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1944 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1945
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1946 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
1947 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1948
7549
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1949 if (--h2c->priority_limit == 0) {
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1950 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1951 "client sent too many PRIORITY frames");
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1952
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1953 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1954 }
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
1955
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1956 if (end - pos < NGX_HTTP_V2_PRIORITY_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1957 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
1958 ngx_http_v2_state_priority);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1961 dependency = ngx_http_v2_parse_uint32(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1962
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1963 depend = dependency & 0x7fffffff;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1964 excl = dependency >> 31;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1965 weight = pos[4] + 1;
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 pos += NGX_HTTP_V2_PRIORITY_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1968
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1969 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
1970 "http2 PRIORITY frame sid:%ui "
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
1971 "depends on %ui excl:%ui weight:%ui",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1972 h2c->state.sid, depend, excl, weight);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1973
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1974 if (h2c->state.sid == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1975 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
1976 "client sent PRIORITY frame with incorrect identifier");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1977
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1978 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
1979 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1980
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1981 if (depend == h2c->state.sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1982 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
1983 "client sent PRIORITY frame for stream %ui "
6284
66ee1c5cb6aa HTTP/2: fixed spelling.
Valentin Bartenev <vbart@nginx.com>
parents: 6280
diff changeset
1984 "with incorrect dependency", h2c->state.sid);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1985
7564
29b2dc731503 HTTP/2: close connection on frames with self-dependency.
Ruslan Ermilov <ru@nginx.com>
parents: 7561
diff changeset
1986 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
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 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
1990
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1991 if (node == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1992 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
1993 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1994
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1995 node->weight = weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1996
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1997 if (node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1998 if (node->parent == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1999 h2c->closed_nodes++;
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 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2002 ngx_queue_remove(&node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2003 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2004
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2005 ngx_queue_insert_tail(&h2c->closed, &node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2006 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2007
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2008 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
2009
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2010 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
2011 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2014 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2015 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
2016 u_char *end)
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_uint_t status;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2019 ngx_event_t *ev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2020 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2021 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2022 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2023
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2024 if (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
2025 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
2026 "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
2027 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2028
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2029 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
2030 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2031
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2032 if (end - pos < NGX_HTTP_V2_RST_STREAM_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2033 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
2034 ngx_http_v2_state_rst_stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2035 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2036
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2037 status = ngx_http_v2_parse_uint32(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2038
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2039 pos += NGX_HTTP_V2_RST_STREAM_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2040
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2041 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2042 "http2 RST_STREAM frame, sid:%ui status:%ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2043 h2c->state.sid, status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2044
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2045 if (h2c->state.sid == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2046 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
2047 "client sent RST_STREAM frame with incorrect identifier");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2048
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2049 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
2050 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2051
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2052 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
2053
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2054 if (node == NULL || node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2055 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
2056 "unknown http2 stream");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2057
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2058 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
2059 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2060
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2061 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2062
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2063 stream->in_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2064 stream->out_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2065
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2066 fc = stream->request->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2067 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2068
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2069 switch (status) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2070
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2071 case NGX_HTTP_V2_CANCEL:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2072 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
2073 "client canceled stream %ui", h2c->state.sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2074 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2075
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2076 case NGX_HTTP_V2_REFUSED_STREAM:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2077 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2078 "client refused stream %ui", h2c->state.sid);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2079 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2080
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2081 case NGX_HTTP_V2_INTERNAL_ERROR:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2082 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
2083 "client terminated stream %ui due to internal error",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2084 h2c->state.sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2085 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2086
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2087 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2088 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
2089 "client terminated stream %ui with status %ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2090 h2c->state.sid, status);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2091 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2092 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2093
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2094 ev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2095 ev->handler(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2096
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2097 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
2098 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2099
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2102 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
2103 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2104 {
7703
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2105 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2106 "http2 SETTINGS frame");
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2107
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2108 if (h2c->state.sid) {
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2109 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2110 "client sent SETTINGS frame with incorrect identifier");
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2111
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2112 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2113 }
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2114
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2115 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
2116
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2117 if (h2c->state.length != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2118 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
2119 "client sent SETTINGS frame with the ACK flag "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2120 "and nonzero length");
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 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
2123 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2124
6514
0aa07850922f HTTP/2: refuse streams with data until SETTINGS is acknowledged.
Valentin Bartenev <vbart@nginx.com>
parents: 6513
diff changeset
2125 h2c->settings_ack = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2126
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2127 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
2128 }
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 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
2131 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
2132 "client sent SETTINGS frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2133 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2134
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2135 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
2136 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2137
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2138 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
2139 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2140
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2141
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2142 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2143 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
2144 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2145 {
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2146 ssize_t window_delta;
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2147 ngx_uint_t id, value;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2148 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
2149 ngx_http_v2_out_frame_t *frame;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2150
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2151 window_delta = 0;
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2152
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2153 while (h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2154 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
2155 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
2156 ngx_http_v2_state_settings_params);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2159 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
2160
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2161 id = ngx_http_v2_parse_uint16(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2162 value = ngx_http_v2_parse_uint32(&pos[2]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2163
7191
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
2164 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
2165 "http2 setting %ui:%ui", id, value);
61d276dcd493 HTTP/2: more style, comments, and debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7190
diff changeset
2166
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2167 switch (id) {
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 case NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2170
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2171 if (value > NGX_HTTP_V2_MAX_WINDOW) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2172 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
2173 "client sent SETTINGS frame with incorrect "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2174 "INITIAL_WINDOW_SIZE value %ui", value);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2175
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2176 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2177 NGX_HTTP_V2_FLOW_CTRL_ERROR);
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
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2180 window_delta = value - h2c->init_window;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2181 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2182
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2183 case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING:
6958
28dc369899ea HTTP/2: style and typos.
Piotr Sikora <piotrsikora@google.com>
parents: 6957
diff changeset
2184
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2185 if (value > NGX_HTTP_V2_MAX_FRAME_SIZE
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2186 || value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2187 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2188 ngx_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
2189 "client sent SETTINGS frame with incorrect "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2190 "MAX_FRAME_SIZE value %ui", value);
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 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2193 NGX_HTTP_V2_PROTOCOL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2194 }
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 h2c->frame_size = value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2197 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2198
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2199 case NGX_HTTP_V2_ENABLE_PUSH_SETTING:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2200
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2201 if (value > 1) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2202 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2203 "client sent SETTINGS frame with incorrect "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2204 "ENABLE_PUSH value %ui", value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2205
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2206 return ngx_http_v2_connection_error(h2c,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2207 NGX_HTTP_V2_PROTOCOL_ERROR);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2208 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2209
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2210 h2c->push_disabled = !value;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2211 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2212
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2213 case NGX_HTTP_V2_MAX_STREAMS_SETTING:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2214 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
2215 ngx_http_v2_module);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2216
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2217 h2c->concurrent_pushes = ngx_min(value, h2scf->concurrent_pushes);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2218 break;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2219
7335
fbb683496705 HTTP/2: workaround for clients which fail on table size updates.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
2220 case NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING:
fbb683496705 HTTP/2: workaround for clients which fail on table size updates.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
2221
fbb683496705 HTTP/2: workaround for clients which fail on table size updates.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
2222 h2c->table_update = 1;
fbb683496705 HTTP/2: workaround for clients which fail on table size updates.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
2223 break;
fbb683496705 HTTP/2: workaround for clients which fail on table size updates.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7296
diff changeset
2224
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2225 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2226 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2227 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2228
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2229 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2230 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2231
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2232 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
2233 NGX_HTTP_V2_SETTINGS_FRAME,
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2234 NGX_HTTP_V2_ACK_FLAG, 0);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2235 if (frame == NULL) {
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2236 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
2237 }
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2238
7025
7206c3630310 HTTP/2: don't send SETTINGS ACK before already queued DATA frames.
Piotr Sikora <piotrsikora@google.com>
parents: 7024
diff changeset
2239 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
2240
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2241 if (window_delta) {
7190
e11a0679d349 HTTP/2: handle duplicate INITIAL_WINDOW_SIZE settings.
Ruslan Ermilov <ru@nginx.com>
parents: 7118
diff changeset
2242 h2c->init_window += window_delta;
e11a0679d349 HTTP/2: handle duplicate INITIAL_WINDOW_SIZE settings.
Ruslan Ermilov <ru@nginx.com>
parents: 7118
diff changeset
2243
7022
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2244 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
2245 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
2246 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
2247 }
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2248 }
645ed7112a01 HTTP/2: emit new frames only after applying all SETTINGS params.
Piotr Sikora <piotrsikora@google.com>
parents: 7016
diff changeset
2249
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2250 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
2251 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2252
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2253
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2254 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2255 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
2256 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2257 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2258 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
2259 "client sent PUSH_PROMISE frame");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2260
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2261 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
2262 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2263
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2264
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2265 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2266 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
2267 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2268 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2269 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2270
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2271 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
2272 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
2273 "client sent PING frame with incorrect length %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2274 h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2275
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2276 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
2277 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2278
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2279 if (end - pos < NGX_HTTP_V2_PING_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2280 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
2281 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2282
7241
190591ab0d76 HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7229
diff changeset
2283 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
190591ab0d76 HTTP/2: improved frame info debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 7229
diff changeset
2284 "http2 PING frame");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2285
7703
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2286 if (h2c->state.sid) {
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2287 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2288 "client sent PING frame with incorrect identifier");
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2289
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2290 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2291 }
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2292
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2293 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
2294 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
2295 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2296
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2297 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
2298 NGX_HTTP_V2_PING_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2299 NGX_HTTP_V2_ACK_FLAG, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2300 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2301 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
2302 }
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 buf = frame->first->buf;
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 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
2307
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2308 ngx_http_v2_queue_blocked_frame(h2c, frame);
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 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
2311 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2312
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2313
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2314 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2315 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
2316 u_char *end)
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 (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2319 ngx_uint_t last_sid, error;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2320 #endif
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 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
2323 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
2324 "client sent GOAWAY frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2325 "with incorrect length %uz", h2c->state.length);
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 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
2328 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2329
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2330 if (end - pos < NGX_HTTP_V2_GOAWAY_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2331 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
2332 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2333
7703
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2334 if (h2c->state.sid) {
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2335 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2336 "client sent GOAWAY frame with incorrect identifier");
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2337
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2338 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2339 }
da5e3f5b1673 HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7695
diff changeset
2340
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2341 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2342 h2c->state.length -= NGX_HTTP_V2_GOAWAY_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2343
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2344 last_sid = ngx_http_v2_parse_sid(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2345 error = ngx_http_v2_parse_uint32(&pos[4]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2346
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2347 pos += NGX_HTTP_V2_GOAWAY_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2348
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2349 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
2350 "http2 GOAWAY frame: last sid %ui, error %ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2351 last_sid, error);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2352 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2353
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2354 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
2355 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2356
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2359 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
2360 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2361 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2362 size_t window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2363 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2364 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2365 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2366 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2367
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2368 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
2369 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
2370 "client sent WINDOW_UPDATE frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2371 "with incorrect length %uz", h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2372
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2373 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
2374 }
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 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
2377 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
2378 ngx_http_v2_state_window_update);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2379 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2380
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2381 window = ngx_http_v2_parse_window(pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2382
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2383 pos += NGX_HTTP_V2_WINDOW_UPDATE_SIZE;
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 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
2386 "http2 WINDOW_UPDATE frame sid:%ui window:%uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2387 h2c->state.sid, window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2388
6988
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2389 if (window == 0) {
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2390 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
7565
fd6dcc6f8a49 HTTP/2: close connection on zero WINDOW_UPDATE.
Ruslan Ermilov <ru@nginx.com>
parents: 7564
diff changeset
2391 "client sent WINDOW_UPDATE frame "
fd6dcc6f8a49 HTTP/2: close connection on zero WINDOW_UPDATE.
Ruslan Ermilov <ru@nginx.com>
parents: 7564
diff changeset
2392 "with incorrect window increment 0");
fd6dcc6f8a49 HTTP/2: close connection on zero WINDOW_UPDATE.
Ruslan Ermilov <ru@nginx.com>
parents: 7564
diff changeset
2393
fd6dcc6f8a49 HTTP/2: close connection on zero WINDOW_UPDATE.
Ruslan Ermilov <ru@nginx.com>
parents: 7564
diff changeset
2394 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
6988
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2395 }
cc823122d50d HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.
Valentin Bartenev <vbart@nginx.com>
parents: 6958
diff changeset
2396
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2397 if (h2c->state.sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2398 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
2399
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2400 if (node == NULL || node->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2401 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
2402 "unknown http2 stream");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2403
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2404 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
2405 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2406
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2407 stream = node->stream;
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 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
2410
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2411 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
2412 "client violated flow control for stream %ui: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2413 "received WINDOW_UPDATE frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2414 "with window increment %uz "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2415 "not allowed for window %z",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2416 h2c->state.sid, window, stream->send_window);
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 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2419 NGX_HTTP_V2_FLOW_CTRL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2420 == NGX_ERROR)
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 return ngx_http_v2_connection_error(h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2423 NGX_HTTP_V2_INTERNAL_ERROR);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2424 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2425
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2426 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
2427 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2428
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2429 stream->send_window += window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2430
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2431 if (stream->exhausted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2432 stream->exhausted = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2433
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2434 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2435
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2436 wev->active = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2437 wev->ready = 1;
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 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2440 wev->handler(wev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2441 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2442 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2443
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2444 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
2445 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2446
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2447 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
2448 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
2449 "client violated connection flow control: "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2450 "received WINDOW_UPDATE frame "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2451 "with window increment %uz "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2452 "not allowed for window %uz",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2453 window, h2c->send_window);
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 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
2456 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2457
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2458 h2c->send_window += window;
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 while (!ngx_queue_empty(&h2c->waiting)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2461 q = ngx_queue_head(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2462
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2463 ngx_queue_remove(q);
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 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
2466
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6805
diff changeset
2467 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2468
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2469 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2470
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2471 wev->active = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2472 wev->ready = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2473
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2474 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2475 wev->handler(wev);
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 if (h2c->send_window == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2478 break;
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 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2481 }
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 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
2484 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2485
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2488 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
2489 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2490 {
6249
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
2491 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
2492 "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
2493
081a073e5164 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
Valentin Bartenev <vbart@nginx.com>
parents: 6248
diff changeset
2494 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
2495 }
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 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2499 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
2500 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2501 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2502 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
2503 "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
2504
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2505 if (pos > end) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2506 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
2507 "receive buffer overrun");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2508
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2509 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
2510 }
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 h2c->state.stream = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2513 h2c->state.handler = ngx_http_v2_state_head;
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 return pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2516 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2517
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2518
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2519 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2520 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
2521 u_char *end)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2522 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2523 h2c->state.length += h2c->state.padding;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2524 h2c->state.padding = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2525
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2526 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
2527 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2528
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2529
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2530 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2531 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
2532 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2533 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2534
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2535 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2536
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2537 if (size < h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2538 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
2539 "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
2540
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2541 h2c->state.length -= size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2542 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
2543 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2544
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2545 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
2546 "http2 frame skip %uz", h2c->state.length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2547
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2548 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
2549 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2550
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2551
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2552 static u_char *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2553 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
2554 ngx_http_v2_handler_pt handler)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2555 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2556 size_t size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2557
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2558 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
2559 "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
2560 pos, end, handler);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2561
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2562 size = end - pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2563
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2564 if (size > NGX_HTTP_V2_STATE_BUFFER_SIZE) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2565 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
2566 "state buffer overflow: %uz bytes required", size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2567
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2568 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
2569 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2570
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2571 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
2572
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2573 h2c->state.buffer_used = size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2574 h2c->state.handler = handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2575 h2c->state.incomplete = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2576
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2577 return end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2578 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2579
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2580
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2581 static u_char *
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2582 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
2583 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
2584 {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2585 ngx_event_t *rev;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2586 ngx_http_request_t *r;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2587 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
2588
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2589 if (h2c->state.stream) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2590 r = h2c->state.stream->request;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2591 rev = r->connection->read;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2592
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2593 if (!rev->timer_set) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2594 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
2595 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
2596 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2597 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2598
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2599 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
2600 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2601
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2602
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
2603 static u_char *
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2604 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
2605 ngx_uint_t err)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2606 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2607 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
2608 "http2 state connection error");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2609
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2610 ngx_http_v2_finalize_connection(h2c, err);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2611
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2612 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2613 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2614
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2615
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2616 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2617 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
2618 ngx_uint_t prefix)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2619 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2620 u_char *start, *p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2621 ngx_uint_t value, octet, shift;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2622
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2623 start = *pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2624 p = start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2625
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2626 value = *p++ & prefix;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2627
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2628 if (value != prefix) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2629 if (h2c->state.length == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2630 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2631 }
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 h2c->state.length--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2634
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2635 *pos = p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2636 return value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2637 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2638
6267
adaac65899c8 HTTP/2: improved HPACK integer parsing code readability.
Ruslan Ermilov <ru@nginx.com>
parents: 6260
diff changeset
2639 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
2640 end = start + NGX_HTTP_V2_INT_OCTETS;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2643 for (shift = 0; p != end; shift += 7) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2644 octet = *p++;
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 value += (octet & 0x7f) << shift;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2647
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2648 if (octet < 128) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2649 if ((size_t) (p - start) > h2c->state.length) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2650 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2651 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2652
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2653 h2c->state.length -= p - start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2654
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2655 *pos = p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2656 return value;
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
6268
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2660 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
2661 return NGX_ERROR;
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2662 }
ee16fb0db905 HTTP/2: improved error handling while parsing integers.
Valentin Bartenev <vbart@nginx.com>
parents: 6267
diff changeset
2663
6267
adaac65899c8 HTTP/2: improved HPACK integer parsing code readability.
Ruslan Ermilov <ru@nginx.com>
parents: 6260
diff changeset
2664 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
2665 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2666 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2667
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2668 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2669 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2670
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2671
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2672 ngx_http_v2_stream_t *
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2673 ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent, ngx_str_t *path)
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2674 {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2675 ngx_int_t rc;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2676 ngx_str_t value;
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2677 ngx_pool_t *pool;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2678 ngx_uint_t index;
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2679 ngx_table_elt_t **h;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2680 ngx_connection_t *fc;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2681 ngx_http_request_t *r;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2682 ngx_http_v2_node_t *node;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2683 ngx_http_v2_stream_t *stream;
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2684 ngx_http_v2_srv_conf_t *h2scf;
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2685 ngx_http_v2_connection_t *h2c;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2686 ngx_http_v2_parse_header_t *header;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2687
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2688 h2c = parent->connection;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2689
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2690 pool = ngx_create_pool(1024, h2c->connection->log);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2691 if (pool == NULL) {
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2692 goto rst_stream;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2693 }
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2694
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2695 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
2696
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2697 if (node == NULL) {
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2698 ngx_destroy_pool(pool);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2699 goto rst_stream;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2700 }
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2701
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2702 stream = ngx_http_v2_create_stream(h2c, 1);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2703 if (stream == NULL) {
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2704
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2705 if (node->parent == NULL) {
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2706 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2707 ngx_http_v2_module);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2708
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2709 index = ngx_http_v2_index(h2scf, h2c->last_push);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2710 h2c->streams_index[index] = node->index;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2711
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2712 ngx_queue_insert_tail(&h2c->closed, &node->reuse);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2713 h2c->closed_nodes++;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2714 }
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2715
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2716 ngx_destroy_pool(pool);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2717 goto rst_stream;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2718 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2719
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2720 if (node->parent) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2721 ngx_queue_remove(&node->reuse);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2722 h2c->closed_nodes--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2723 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2724
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2725 stream->pool = pool;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2726
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2727 r = stream->request;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2728 fc = r->connection;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2729
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2730 stream->in_closed = 1;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2731 stream->node = node;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2732
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2733 node->stream = stream;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2734
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2735 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
2736 "http2 push stream sid:%ui "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2737 "depends on %ui excl:0 weight:16",
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2738 h2c->last_push, parent->node->id);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2739
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2740 node->weight = NGX_HTTP_V2_DEFAULT_WEIGHT;
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2741 ngx_http_v2_set_dependency(h2c, node, parent->node->id, 0);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2742
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2743 r->method_name = ngx_http_core_get_method;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2744 r->method = NGX_HTTP_GET;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2745
7296
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7295
diff changeset
2746 r->schema.data = ngx_pstrdup(pool, &parent->request->schema);
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7295
diff changeset
2747 if (r->schema.data == NULL) {
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7295
diff changeset
2748 goto close;
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7295
diff changeset
2749 }
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7295
diff changeset
2750
8e6bb4e6045f HTTP/2: use scheme from original request for pushes (closes #1549).
Ruslan Ermilov <ru@nginx.com>
parents: 7295
diff changeset
2751 r->schema.len = parent->request->schema.len;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2752
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2753 value.data = ngx_pstrdup(pool, path);
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2754 if (value.data == NULL) {
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2755 goto close;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2756 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2757
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2758 value.len = path->len;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2759
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2760 rc = ngx_http_v2_parse_path(r, &value);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2761
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2762 if (rc != NGX_OK) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2763 goto error;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2764 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2765
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2766 for (header = ngx_http_v2_parse_headers; header->name.len; header++) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2767 h = (ngx_table_elt_t **)
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2768 ((char *) &parent->request->headers_in + header->offset);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2769
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2770 if (*h == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2771 continue;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2772 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2773
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2774 value.len = (*h)->value.len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2775
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2776 value.data = ngx_pnalloc(pool, value.len + 1);
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2777 if (value.data == NULL) {
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2778 goto close;
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2779 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2780
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2781 ngx_memcpy(value.data, (*h)->value.data, value.len);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2782 value.data[value.len] = '\0';
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2783
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2784 rc = ngx_http_v2_parse_header(r, header, &value);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2785
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2786 if (rc != NGX_OK) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2787 goto error;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2788 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2789 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2790
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2791 fc->write->handler = ngx_http_v2_run_request_handler;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2792 ngx_post_event(fc->write, &ngx_posted_events);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2793
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2794 return stream;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2795
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2796 error:
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2797
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2798 if (rc == NGX_ABORT) {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2799 /* header handler has already finalized request */
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
2800 ngx_http_run_posted_requests(fc);
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2801 return NULL;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2802 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2803
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2804 if (rc == NGX_DECLINED) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2805 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
2806 ngx_http_run_posted_requests(fc);
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2807 return NULL;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2808 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2809
7208
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2810 close:
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2811
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2812 ngx_http_v2_close_stream(stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2813
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2814 return NULL;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2815
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2816 rst_stream:
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2817
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2818 if (ngx_http_v2_send_rst_stream(h2c, h2c->last_push,
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2819 NGX_HTTP_INTERNAL_SERVER_ERROR)
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2820 != NGX_OK)
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2821 {
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2822 h2c->connection->error = 1;
affeb6ef732c HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.
Ruslan Ermilov <ru@nginx.com>
parents: 7207
diff changeset
2823 }
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2824
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
2825 return NULL;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2826 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2827
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
2828
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2829 static ngx_int_t
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2830 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
2831 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2832 size_t len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2833 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2834 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2835 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2836 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2837
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2838 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
2839 "http2 send SETTINGS frame");
6246
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 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
2842 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2843 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2844 }
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 cl = ngx_alloc_chain_link(h2c->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2847 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2848 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2849 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2850
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2851 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
2852
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2853 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
2854 if (buf == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2855 return NGX_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2858 buf->last_buf = 1;
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 cl->buf = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2861 cl->next = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2862
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2863 frame->first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2864 frame->last = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2865 frame->handler = ngx_http_v2_settings_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2866 frame->stream = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2867 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2868 frame->length = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2869 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2870 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2871
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2872 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
2873 NGX_HTTP_V2_SETTINGS_FRAME);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2874
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2875 *buf->last++ = NGX_HTTP_V2_NO_FLAG;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2876
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2877 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
2878
7024
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2879 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
2880 ngx_http_v2_module);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2881
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2882 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
2883 NGX_HTTP_V2_MAX_STREAMS_SETTING);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2884 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
2885 h2scf->concurrent_streams);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2886
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2887 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
2888 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
2889 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
2890
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2891 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
2892 NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING);
79de0d2aa432 HTTP/2: make SETTINGS ACK frame reusable.
Piotr Sikora <piotrsikora@google.com>
parents: 7023
diff changeset
2893 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
2894 NGX_HTTP_V2_MAX_FRAME_SIZE);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2895
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2896 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2897
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2898 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2899 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2902 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2903 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
2904 ngx_http_v2_out_frame_t *frame)
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 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2907
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2908 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2909
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2910 if (buf->pos != buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2911 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2912 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2913
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2914 ngx_free_chain(h2c->pool, frame->first);
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 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2917 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2918
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2919
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2920 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2921 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
2922 size_t window)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2923 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2924 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2925 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2926
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2927 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
2928 "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
2929 sid, window);
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2930
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2931 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
2932 NGX_HTTP_V2_WINDOW_UPDATE_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2933 NGX_HTTP_V2_NO_FLAG, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2934 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2935 return NGX_ERROR;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2938 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2939
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2940 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
2941
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2942 ngx_http_v2_queue_blocked_frame(h2c, frame);
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 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2945 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2946
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2947
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2948 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2949 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
2950 ngx_uint_t status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2951 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2952 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2953 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2954
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2955 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
2956 "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
2957 sid, status);
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2958
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2959 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
2960 NGX_HTTP_V2_RST_STREAM_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2961 NGX_HTTP_V2_NO_FLAG, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2962 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2963 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2964 }
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 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2967
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2968 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
2969
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2970 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2971
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2972 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2973 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2976 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2977 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
2978 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2979 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2980 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2981
6790
727c6412673a HTTP/2: slightly improved debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 6783
diff changeset
2982 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
2983 "http2 send GOAWAY frame: last sid %ui, error %ui",
727c6412673a HTTP/2: slightly improved debugging.
Ruslan Ermilov <ru@nginx.com>
parents: 6783
diff changeset
2984 h2c->last_sid, status);
6448
4d1d3c2530e0 HTTP/2: improved debugging of sending control frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6412
diff changeset
2985
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2986 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
2987 NGX_HTTP_V2_GOAWAY_FRAME,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2988 NGX_HTTP_V2_NO_FLAG, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2989 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2990 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2991 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2992
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2993 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2994
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2995 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
2996 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
2997
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2998 ngx_http_v2_queue_blocked_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2999
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3000 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3001 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3002
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 static ngx_http_v2_out_frame_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3005 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
3006 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
3007 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3008 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3009 ngx_pool_t *pool;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3010 ngx_http_v2_out_frame_t *frame;
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 frame = h2c->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3013
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3014 if (frame) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3015 h2c->free_frames = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3016
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3017 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3018 buf->pos = buf->start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3019
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3020 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3021
7377
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3022 } else if (h2c->frames < 10000) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3023 pool = h2c->pool ? h2c->pool : h2c->connection->pool;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3024
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3025 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
3026 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3027 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3028 }
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 frame->first = ngx_alloc_chain_link(pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3031 if (frame->first == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3032 return NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3035 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
3036 if (buf == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3037 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3038 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3039
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3040 buf->last_buf = 1;
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 frame->first->buf = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3043 frame->last = frame->first;
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 frame->handler = ngx_http_v2_frame_handler;
7377
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3046
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3047 h2c->frames++;
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3048
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3049 } else {
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3050 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3051 "http2 flood detected");
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3052
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3053 h2c->connection->error = 1;
d4448892a294 HTTP/2: flood detection.
Ruslan Ermilov <ru@nginx.com>
parents: 7354
diff changeset
3054 return NULL;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3055 }
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 #if (NGX_DEBUG)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3058 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
3059 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3060 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
3061 "requested control frame is too large: %uz", length);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3062 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3063 }
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3064 #endif
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3065
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3066 frame->length = length;
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 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
3069
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3070 *buf->last++ = flags;
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 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
3073
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3074 return frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3075 }
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 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3079 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
3080 ngx_http_v2_out_frame_t *frame)
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_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3083
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3084 buf = frame->first->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3085
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3086 if (buf->pos != buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3087 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3088 }
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 frame->next = h2c->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3091 h2c->free_frames = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3092
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3093 h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3094
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3095 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3096 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3099 static ngx_http_v2_stream_t *
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3100 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
3101 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3102 ngx_log_t *log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3103 ngx_event_t *rev, *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3104 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3105 ngx_http_log_ctx_t *ctx;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3106 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3107 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
3108 ngx_http_v2_srv_conf_t *h2scf;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3109 ngx_http_core_srv_conf_t *cscf;
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 fc = h2c->free_fake_connections;
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 if (fc) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3114 h2c->free_fake_connections = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3115
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3116 rev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3117 wev = fc->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3118 log = fc->log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3119 ctx = log->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3120
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3121 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3122 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
3123 if (fc == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3124 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3125 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3126
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3127 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
3128 if (rev == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3129 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3130 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3131
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3132 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
3133 if (wev == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3134 return NULL;
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 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
3138 if (log == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3139 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3140 }
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 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
3143 if (ctx == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3144 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3145 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3146
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3147 ctx->connection = fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3148 ctx->request = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3149 ctx->current_request = NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3152 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
3153
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3154 log->data = ctx;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3155
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3156 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3157 log->action = "processing pushed request headers";
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3158
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3159 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3160 log->action = "reading client request headers";
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3161 }
6246
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 ngx_memzero(rev, sizeof(ngx_event_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3164
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3165 rev->data = fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3166 rev->ready = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3167 rev->handler = ngx_http_v2_close_stream_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3168 rev->log = log;
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 ngx_memcpy(wev, rev, sizeof(ngx_event_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3171
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3172 wev->write = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3173
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3174 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
3175
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3176 fc->data = h2c->http_connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3177 fc->read = rev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3178 fc->write = wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3179 fc->sent = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3180 fc->log = log;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3181 fc->buffered = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3182 fc->sndlowat = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3183 fc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
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 r = ngx_http_create_request(fc);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3186 if (r == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3187 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3188 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3189
6256
9dfc4ba140f9 HTTP/2: fixed $server_protocol value (ticket #800).
Valentin Bartenev <vbart@nginx.com>
parents: 6249
diff changeset
3190 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
3191
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3192 r->http_version = NGX_HTTP_VERSION_20;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3193 r->valid_location = 1;
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 fc->data = r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3196 h2c->connection->requests++;
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 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
3199
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3200 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
3201 cscf->client_header_buffer_size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3202 if (r->header_in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3203 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
3204 return NULL;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3207 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
3208 sizeof(ngx_table_elt_t))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3209 != NGX_OK)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3210 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3211 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
3212 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3213 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3214
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3215 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
3216
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3217 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
3218 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3219 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
3220 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3221 }
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 r->stream = stream;
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 stream->request = r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3226 stream->connection = h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3227
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3228 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
3229
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3230 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
3231 stream->recv_window = h2scf->preread_size;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3232
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3233 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3234 h2c->pushing++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3235
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3236 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3237 h2c->processing++;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3238 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3239
7549
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
3240 h2c->priority_limit += h2scf->concurrent_streams;
45415228990b HTTP/2: limited number of PRIORITY frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7548
diff changeset
3241
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3242 return stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3243 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3246 static ngx_http_v2_node_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3247 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
3248 ngx_uint_t alloc)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3249 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3250 ngx_uint_t index;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3251 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3252 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3253
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3254 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
3255 ngx_http_v2_module);
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 index = ngx_http_v2_index(h2scf, sid);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3258
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3259 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
3260
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3261 if (node->id == sid) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3262 return node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3263 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3264 }
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 if (!alloc) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3267 return NULL;
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 if (h2c->closed_nodes < 32) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3271 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
3272 if (node == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3273 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3274 }
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 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3277 node = ngx_http_v2_get_closed_node(h2c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3278 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3279
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3280 node->id = sid;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3281
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3282 ngx_queue_init(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3283
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3284 node->index = h2c->streams_index[index];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3285 h2c->streams_index[index] = node;
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 return node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3288 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3289
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3290
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3291 static ngx_http_v2_node_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3292 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
3293 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3294 ngx_uint_t weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3295 ngx_queue_t *q, *children;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3296 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
3297 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3298
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3299 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
3300 ngx_http_v2_module);
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 h2c->closed_nodes--;
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 q = ngx_queue_head(&h2c->closed);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3305
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3306 ngx_queue_remove(q);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3307
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3308 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
3309
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3310 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
3311
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3312 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3313 n = *next;
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 if (n == node) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3316 *next = n->index;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3317 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3318 }
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 next = &n->index;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3321 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3322
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3323 ngx_queue_remove(&node->queue);
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 weight = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3326
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3327 for (q = ngx_queue_head(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3328 q != ngx_queue_sentinel(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3329 q = ngx_queue_next(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3330 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3331 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
3332 weight += child->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3333 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3334
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
3335 parent = node->parent;
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
3336
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3337 for (q = ngx_queue_head(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3338 q != ngx_queue_sentinel(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3339 q = ngx_queue_next(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3340 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3341 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
3342 child->parent = parent;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3343 child->weight = node->weight * child->weight / weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3344
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3345 if (child->weight == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3346 child->weight = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3347 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3348 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3349
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3350 if (parent == NGX_HTTP_V2_ROOT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3351 node->rank = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3352 node->rel_weight = 1.0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3353
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3354 children = &h2c->dependencies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3355
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3356 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3357 node->rank = parent->rank;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3358 node->rel_weight = parent->rel_weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3359
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3360 children = &parent->children;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3363 ngx_http_v2_node_children_update(node);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3364 ngx_queue_add(children, &node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3365
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3366 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
3367
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3368 return node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3369 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3370
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 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3373 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
3374 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3375 u_char ch;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3376 ngx_uint_t i;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3377 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3378
6291
932a465537ef HTTP/2: fixed invalid headers handling (ticket #831).
Valentin Bartenev <vbart@nginx.com>
parents: 6288
diff changeset
3379 r->invalid_header = 0;
932a465537ef HTTP/2: fixed invalid headers handling (ticket #831).
Valentin Bartenev <vbart@nginx.com>
parents: 6288
diff changeset
3380
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3381 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
3382
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3383 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
3384 ch = header->name.data[i];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3385
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3386 if ((ch >= 'a' && ch <= 'z')
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3387 || (ch == '-')
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3388 || (ch >= '0' && ch <= '9')
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3389 || (ch == '_' && cscf->underscores_in_headers))
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 continue;
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
7216
aa60f5799a4c HTTP/2: style.
Ruslan Ermilov <ru@nginx.com>
parents: 7209
diff changeset
3394 if (ch == '\0' || ch == LF || ch == CR || ch == ':'
aa60f5799a4c HTTP/2: style.
Ruslan Ermilov <ru@nginx.com>
parents: 7209
diff changeset
3395 || (ch >= 'A' && ch <= 'Z'))
aa60f5799a4c HTTP/2: style.
Ruslan Ermilov <ru@nginx.com>
parents: 7209
diff changeset
3396 {
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 header name: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3399 &header->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_ERROR;
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 r->invalid_header = 1;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3407 for (i = 0; i != header->value.len; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3408 ch = header->value.data[i];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3409
7216
aa60f5799a4c HTTP/2: style.
Ruslan Ermilov <ru@nginx.com>
parents: 7209
diff changeset
3410 if (ch == '\0' || ch == LF || ch == CR) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3411 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
3412 "client sent header \"%V\" with "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3413 "invalid value: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3414 &header->name, &header->value);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3415
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3416 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3417 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3420 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3421 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3422
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3423
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3424 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3425 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
3426 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3427 header->name.len--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3428 header->name.data++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3429
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3430 switch (header->name.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3431 case 4:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3432 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
3433 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3434 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3435 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
3436 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3437
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3438 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3439
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3440 case 6:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3441 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
3442 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3443 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3444 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
3445 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3446
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3447 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
3448 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3449 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3450 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
3451 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3452
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3453 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3454
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3455 case 9:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3456 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
3457 == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3458 {
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3459 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
3460 }
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 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3463 }
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 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
3466 "client sent unknown pseudo-header \":%V\"",
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3467 &header->name);
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 return NGX_DECLINED;
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3472
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3473 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3474 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
3475 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3476 if (r->unparsed_uri.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3477 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
3478 "client sent duplicate :path header");
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 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3481 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3482
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3483 if (value->len == 0) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3484 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
3485 "client sent empty :path header");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3486
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3487 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3488 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3489
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3490 r->uri_start = value->data;
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3491 r->uri_end = value->data + value->len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3492
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3493 if (ngx_http_parse_uri(r) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3494 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
3495 "client sent invalid :path header: \"%V\"", value);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3496
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3497 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3498 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3499
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3500 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
3501 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3502 * request has been finalized already
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3503 * in ngx_http_process_request_uri()
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3504 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3505 return NGX_ABORT;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3506 }
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 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3509 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3510
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3511
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3512 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3513 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
3514 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3515 size_t k, len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3516 ngx_uint_t n;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3517 const u_char *p, *m;
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 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3520 * This array takes less than 256 sequential bytes,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3521 * 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
3522 * it is prefetched for 4 load operations.
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3523 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3524 static const struct {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3525 u_char len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3526 const u_char method[11];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3527 uint32_t value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3528 } tests[] = {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3529 { 3, "GET", NGX_HTTP_GET },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3530 { 4, "POST", NGX_HTTP_POST },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3531 { 4, "HEAD", NGX_HTTP_HEAD },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3532 { 7, "OPTIONS", NGX_HTTP_OPTIONS },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3533 { 8, "PROPFIND", NGX_HTTP_PROPFIND },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3534 { 3, "PUT", NGX_HTTP_PUT },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3535 { 5, "MKCOL", NGX_HTTP_MKCOL },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3536 { 6, "DELETE", NGX_HTTP_DELETE },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3537 { 4, "COPY", NGX_HTTP_COPY },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3538 { 4, "MOVE", NGX_HTTP_MOVE },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3539 { 9, "PROPPATCH", NGX_HTTP_PROPPATCH },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3540 { 4, "LOCK", NGX_HTTP_LOCK },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3541 { 6, "UNLOCK", NGX_HTTP_UNLOCK },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3542 { 5, "PATCH", NGX_HTTP_PATCH },
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3543 { 5, "TRACE", NGX_HTTP_TRACE }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3544 }, *test;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3545
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3546 if (r->method_name.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3547 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
3548 "client sent duplicate :method header");
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 return NGX_DECLINED;
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
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3553 if (value->len == 0) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3554 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
3555 "client sent empty :method header");
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 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3558 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3559
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3560 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
3561 r->method_name.data = value->data;
6246
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 len = r->method_name.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3564 n = sizeof(tests) / sizeof(tests[0]);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3565 test = tests;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3566
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3567 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3568 if (len == test->len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3569 p = r->method_name.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3570 m = test->method;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3571 k = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3572
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3573 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3574 if (*p++ != *m++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3575 goto next;
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 } while (--k);
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 r->method = test->value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3580 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3581 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3582
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3583 next:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3584 test++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3585
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3586 } while (--n);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3587
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3588 p = r->method_name.data;
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 {
6732
57148b755320 Allowed '-' in method names.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6642
diff changeset
3591 if ((*p < 'A' || *p > 'Z') && *p != '_' && *p != '-') {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3592 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
3593 "client sent invalid method: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3594 &r->method_name);
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 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3597 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3598
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3599 p++;
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 } while (--len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3602
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3603 return NGX_OK;
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
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 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3608 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
3609 {
7293
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3610 u_char c, ch;
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3611 ngx_uint_t i;
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3612
7295
89430899c72a Added r->schema.
Ruslan Ermilov <ru@nginx.com>
parents: 7293
diff changeset
3613 if (r->schema.len) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3614 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
3615 "client sent duplicate :scheme header");
6246
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 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3618 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3619
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3620 if (value->len == 0) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3621 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
3622 "client sent empty :scheme header");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3623
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3624 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3625 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3626
7293
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3627 for (i = 0; i < value->len; i++) {
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3628 ch = value->data[i];
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3629
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3630 c = (u_char) (ch | 0x20);
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3631 if (c >= 'a' && c <= 'z') {
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3632 continue;
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3633 }
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3634
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3635 if (((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.')
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3636 && i > 0)
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3637 {
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3638 continue;
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3639 }
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3640
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3641 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3642 "client sent invalid :scheme header: \"%V\"", value);
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3643
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3644 return NGX_DECLINED;
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3645 }
d588987701f4 HTTP/2: validate client request scheme.
Ruslan Ermilov <ru@nginx.com>
parents: 7241
diff changeset
3646
7295
89430899c72a Added r->schema.
Ruslan Ermilov <ru@nginx.com>
parents: 7293
diff changeset
3647 r->schema = *value;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3648
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3649 return NGX_OK;
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
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 static ngx_int_t
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3654 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
3655 {
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3656 return ngx_http_v2_parse_header(r, &ngx_http_v2_parse_headers[0], value);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3657 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3658
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3659
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3660 static ngx_int_t
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3661 ngx_http_v2_parse_header(ngx_http_request_t *r,
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3662 ngx_http_v2_parse_header_t *header, ngx_str_t *value)
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3663 {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3664 ngx_table_elt_t *h;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3665 ngx_http_core_main_conf_t *cmcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3666
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3667 h = ngx_list_push(&r->headers_in.headers);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3668 if (h == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3669 return NGX_ERROR;
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
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3672 h->key.len = header->name.len;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3673 h->key.data = header->name.data;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3674 h->lowcase_key = header->name.data;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3675
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3676 if (header->hh == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3677 header->hash = ngx_hash_key(header->name.data, header->name.len);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3678
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3679 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3680
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3681 header->hh = ngx_hash_find(&cmcf->headers_in_hash, header->hash,
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3682 h->lowcase_key, h->key.len);
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3683 if (header->hh == NULL) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3684 return NGX_ERROR;
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3685 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3686 }
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3687
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3688 h->hash = header->hash;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3689
7200
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3690 h->value.len = value->len;
cadb43014c7c HTTP/2: changed prototypes of request pseudo-headers parsers.
Ruslan Ermilov <ru@nginx.com>
parents: 7192
diff changeset
3691 h->value.data = value->data;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3692
7207
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3693 if (header->hh->handler(r, h, header->hh->offset) != NGX_OK) {
3d2b0b02bd3d HTTP/2: push additional request headers (closes #1478).
Ruslan Ermilov <ru@nginx.com>
parents: 7204
diff changeset
3694 /* header handler has already finalized request */
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3695 return NGX_ABORT;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3696 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3697
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3698 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3699 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3700
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3701
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3702 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3703 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
3704 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3705 u_char *p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3706
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3707 static const u_char ending[] = " HTTP/2.0";
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3708
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3709 if (r->method_name.len == 0
7295
89430899c72a Added r->schema.
Ruslan Ermilov <ru@nginx.com>
parents: 7293
diff changeset
3710 || r->schema.len == 0
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3711 || r->unparsed_uri.len == 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3712 {
7106
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3713 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
3714 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
3715 "client sent no :method header");
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3716
7295
89430899c72a Added r->schema.
Ruslan Ermilov <ru@nginx.com>
parents: 7293
diff changeset
3717 } else if (r->schema.len == 0) {
7106
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3718 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
3719 "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
3720
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3721 } else {
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3722 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
3723 "client sent no :path header");
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3724 }
d77407baccd1 HTTP/2: added logging of 400 (Bad Request) reasons.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7100
diff changeset
3725
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3726 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
3727 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3728 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3729
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3730 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
3731 + r->unparsed_uri.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3732 + sizeof(ending) - 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3733
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3734 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
3735 if (p == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3736 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
3737 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3738 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3739
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3740 r->request_line.data = p;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3741
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3742 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
3743
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3744 *p++ = ' ';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3745
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3746 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
3747
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3748 ngx_memcpy(p, ending, sizeof(ending));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3749
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3750 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
3751 "http2 request line: \"%V\"", &r->request_line);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3752
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3753 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3754 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3755
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3756
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3757 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3758 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
3759 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3760 ngx_str_t *val;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3761 ngx_array_t *cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3762
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3763 cookies = r->stream->cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3764
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3765 if (cookies == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3766 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
3767 if (cookies == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3768 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3769 }
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 r->stream->cookies = cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3772 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3773
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3774 val = ngx_array_push(cookies);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3775 if (val == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3776 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3777 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3778
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3779 val->len = header->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3780 val->data = header->value.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3781
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3782 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3783 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3784
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3785
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3786 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3787 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
3788 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3789 u_char *buf, *p, *end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3790 size_t len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3791 ngx_str_t *vals;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3792 ngx_uint_t i;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3793 ngx_array_t *cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3794 ngx_table_elt_t *h;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3795 ngx_http_header_t *hh;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3796 ngx_http_core_main_conf_t *cmcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3797
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3798 static ngx_str_t cookie = ngx_string("cookie");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3799
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3800 cookies = r->stream->cookies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3801
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3802 if (cookies == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3803 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3804 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3805
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3806 vals = cookies->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3807
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3808 i = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3809 len = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3810
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3811 do {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3812 len += vals[i].len + 2;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3813 } while (++i != cookies->nelts);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3814
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3815 len -= 2;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3816
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3817 buf = ngx_pnalloc(r->pool, len + 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3818 if (buf == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3819 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
3820 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3821 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3822
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3823 p = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3824 end = buf + len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3825
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3826 for (i = 0; /* void */ ; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3827
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3828 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
3829
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3830 if (p == end) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3831 *p = '\0';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3832 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3833 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3834
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3835 *p++ = ';'; *p++ = ' ';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3836 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3837
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3838 h = ngx_list_push(&r->headers_in.headers);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3839 if (h == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3840 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
3841 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3842 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3843
7209
3dfe9444324b HTTP/2: precalculate hash for "Cookie".
Maxim Dounin <mdounin@mdounin.ru>
parents: 7208
diff changeset
3844 h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
3dfe9444324b HTTP/2: precalculate hash for "Cookie".
Maxim Dounin <mdounin@mdounin.ru>
parents: 7208
diff changeset
3845 ngx_hash('c', 'o'), 'o'), 'k'), 'i'), 'e');
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3846
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3847 h->key.len = cookie.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3848 h->key.data = cookie.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3849
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3850 h->value.len = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3851 h->value.data = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3852
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3853 h->lowcase_key = cookie.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3854
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3855 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
3856
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3857 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
3858 h->lowcase_key, h->key.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3859
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3860 if (hh == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3861 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
3862 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3863 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3864
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3865 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
3866 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3867 * request has been finalized already
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3868 * in ngx_http_process_multi_header_lines()
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3869 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3870 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3871 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3872
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3873 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3874 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3875
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3876
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3877 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3878 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
3879 {
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3880 ngx_connection_t *fc;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3881 ngx_http_v2_connection_t *h2c;
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3882
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3883 fc = r->connection;
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3884
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3885 if (ngx_http_v2_construct_request_line(r) != NGX_OK) {
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3886 goto failed;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3887 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3888
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3889 if (ngx_http_v2_construct_cookie_header(r) != NGX_OK) {
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3890 goto failed;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3891 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3892
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3893 r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3894
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3895 if (ngx_http_process_request_header(r) != NGX_OK) {
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3896 goto failed;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3897 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3898
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3899 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
3900 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
3901 "client prematurely closed stream");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3902
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3903 r->stream->skip_data = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3904
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3905 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3906 goto failed;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3907 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3908
6589
78533a74af11 HTTP/2: avoid adding Content-Length for requests without body.
Valentin Bartenev <vbart@nginx.com>
parents: 6588
diff changeset
3909 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
3910 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
3911 }
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3912
7569
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3913 h2c = r->stream->connection;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3914
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3915 h2c->payload_bytes += r->request_length;
80359395b345 HTTP/2: traffic-based flood detection.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7568
diff changeset
3916
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3917 ngx_http_process_request(r);
7354
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3918
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3919 failed:
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3920
1812f1d79d84 Fixed socket leak with "return 444" in error_page (ticket #274).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7335
diff changeset
3921 ngx_http_run_posted_requests(fc);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3922 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3923
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3924
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3925 static void
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3926 ngx_http_v2_run_request_handler(ngx_event_t *ev)
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3927 {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3928 ngx_connection_t *fc;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3929 ngx_http_request_t *r;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3930
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3931 fc = ev->data;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3932 r = fc->data;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3933
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3934 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3935 "http2 run request handler");
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3936
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3937 ngx_http_v2_run_request(r);
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3938 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3939
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
3940
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3941 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
3942 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
3943 {
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3944 off_t len;
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3945 size_t size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3946 ngx_buf_t *buf;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3947 ngx_int_t rc;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
3948 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
3949 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
3950 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
3951 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
3952 ngx_http_v2_connection_t *h2c;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3953
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3954 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
3955 rb = r->request_body;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3956
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3957 if (stream->skip_data) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3958 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
3959 rb->post_handler(r);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3960 return NGX_OK;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3961 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3962
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3963 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
3964 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
3965
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3966 len = r->headers_in.content_length_n;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3967
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3968 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
3969
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3970 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
3971 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
3972 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3973
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3974 /*
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3975 * 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
3976 * 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
3977 */
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3978
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3979 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
3980 len = h2scf->preread_size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3981 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3982
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
3983 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
3984 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
3985 }
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3986
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3987 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
3988
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
3989 } 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
3990 && !r->request_body_in_file_only)
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3991 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3992 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
3993
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3994 } else {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3995 rb->buf = ngx_calloc_buf(r->pool);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3996
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3997 if (rb->buf != NULL) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
3998 rb->buf->sync = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3999 }
6496
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 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
4003 stream->skip_data = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4004 return NGX_HTTP_INTERNAL_SERVER_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4005 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4006
6989
2c4dbcd6f2e4 HTTP/2: reduced difference to HTTP/1.x in reading request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6988
diff changeset
4007 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
4008
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4009 buf = stream->preread;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4010
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4011 if (stream->in_closed) {
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4012 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
4013
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4014 if (buf) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4015 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
4016 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
4017 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
4018 return rc;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4019 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4020
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4021 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
4022 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4023
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4024 if (buf) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4025 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
4026 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
4027
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4028 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
4029
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4030 if (rc != NGX_OK) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4031 stream->skip_data = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4032 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
4033 }
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4034 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4035
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4036 if (r->request_body_no_buffering) {
6572
bc6fd7afeed6 HTTP/2: unbreak build on MSVC.
Valentin Bartenev <vbart@nginx.com>
parents: 6566
diff changeset
4037 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
4038
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4039 } else {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4040 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
4041 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
4042 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4043
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4044 if (size) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4045 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
4046 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
4047 == NGX_ERROR)
7760b54d5458 HTTP/2: don't send WINDOW_UPDATE for an empty request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6516
diff changeset
4048 {
6519
9ac934dd5dd8 HTTP/2: skip data frames in case of internal errors.
Valentin Bartenev <vbart@nginx.com>
parents: 6518
diff changeset
4049 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
4050 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
4051 }
6520
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4052
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4053 h2c = stream->connection;
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4054
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4055 if (!h2c->blocked) {
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4056 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
4057 stream->skip_data = 1;
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4058 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
4059 }
9070ba416284 HTTP/2: send the output queue after emitting WINDOW_UPDATE.
Valentin Bartenev <vbart@nginx.com>
parents: 6519
diff changeset
4060 }
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4061
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4062 stream->recv_window += size;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4063 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4064
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4065 if (!buf) {
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4066 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
4067 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4068
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4069 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
4070 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
4071
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4072 return NGX_AGAIN;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4073 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4074
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4075
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4076 static ngx_int_t
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4077 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
4078 size_t size, ngx_uint_t last)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4079 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4080 ngx_buf_t *buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4081 ngx_int_t rc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4082 ngx_connection_t *fc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4083 ngx_http_request_body_t *rb;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4084 ngx_http_core_loc_conf_t *clcf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4085
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4086 fc = r->connection;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4087 rb = r->request_body;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4088 buf = rb->buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4089
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4090 if (size) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4091 if (buf->sync) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4092 buf->pos = buf->start = pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4093 buf->last = buf->end = pos + size;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4094
7118
b6dc472299da HTTP/2: enforce writing the sync request body buffer to file.
Valentin Bartenev <vbart@nginx.com>
parents: 7108
diff changeset
4095 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
4096
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4097 } else {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4098 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
4099 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
7204
e44c297a6b95 HTTP/2: style.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7201
diff changeset
4100 "client intended to send body data "
e44c297a6b95 HTTP/2: style.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7201
diff changeset
4101 "larger than declared");
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4102
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4103 return NGX_HTTP_BAD_REQUEST;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4104 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4105
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4106 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
4107 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4108 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4109
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4110 if (last) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4111 rb->rest = 0;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4112
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4113 if (fc->read->timer_set) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4114 ngx_del_timer(fc->read);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4115 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4116
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4117 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
4118 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
4119 return NGX_OK;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4120 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4121
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4122 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
4123
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4124 if (rc != NGX_OK) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4125 return rc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4126 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4127
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4128 if (buf->sync) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4129 /* 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
4130 rb->buf = NULL;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4131 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4132
6589
78533a74af11 HTTP/2: avoid adding Content-Length for requests without body.
Valentin Bartenev <vbart@nginx.com>
parents: 6588
diff changeset
4133 if (r->headers_in.chunked) {
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4134 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
4135 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4136
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4137 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
4138 rb->post_handler(r);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4139
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4140 return NGX_OK;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4141 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4142
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4143 if (size == 0) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4144 return NGX_OK;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4145 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4146
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4147 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
4148 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
4149
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4150 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
4151 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
4152 return NGX_OK;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4153 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4154
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4155 if (buf->sync) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4156 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
4157 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4158
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4159 return NGX_OK;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4160 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4161
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4162
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4163 static ngx_int_t
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4164 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
4165 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4166 ngx_buf_t *b, *buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4167 ngx_int_t rc;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4168 ngx_chain_t *cl;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4169 ngx_http_request_body_t *rb;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4170 ngx_http_core_loc_conf_t *clcf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4171
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4172 rb = r->request_body;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4173 buf = rb->buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4174
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4175 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
4176 cl = NULL;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4177 goto update;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4178 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4179
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4180 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
4181 if (cl == NULL) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4182 return NGX_HTTP_INTERNAL_SERVER_ERROR;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4183 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4184
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4185 b = cl->buf;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4186
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4187 ngx_memzero(b, sizeof(ngx_buf_t));
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4188
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4189 if (buf->pos != buf->last) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4190 r->request_length += buf->last - buf->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4191 rb->received += buf->last - buf->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4192
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4193 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
4194 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
4195 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
4196 "client intended to send body data "
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4197 "larger than declared");
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4198
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4199 return NGX_HTTP_BAD_REQUEST;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4200 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4201
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4202 } else {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4203 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
4204
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4205 if (clcf->client_max_body_size
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4206 && rb->received > clcf->client_max_body_size)
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4207 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4208 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
4209 "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
4210 "%O bytes", rb->received);
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4211
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4212 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4213 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4214 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4215
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4216 b->temporary = 1;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4217 b->pos = buf->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4218 b->last = buf->last;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4219 b->start = b->pos;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4220 b->end = b->last;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4221
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4222 buf->pos = buf->last;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4223 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4224
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4225 if (!rb->rest) {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4226 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
4227 && 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
4228 {
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4229 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
4230 "client prematurely closed stream: "
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4231 "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
4232 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
4233
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4234 return NGX_HTTP_BAD_REQUEST;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4235 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4236
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4237 b->last_buf = 1;
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4238 }
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4239
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4240 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
4241 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
4242
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4243 update:
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4244
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4245 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
4246
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4247 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
4248 (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
4249
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4250 return rc;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4251 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4252
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4253
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4254 static void
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4255 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
4256 {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4257 ngx_connection_t *fc;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4258
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4259 fc = r->connection;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4260
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4261 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
4262 "http2 read client request body handler");
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4263
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4264 if (fc->read->timedout) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4265 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
4266
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4267 fc->timedout = 1;
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4268 r->stream->skip_data = 1;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4269
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4270 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
4271 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4272 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4273
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4274 if (fc->error) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4275 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
4276 "client prematurely closed stream");
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4277
6496
887cca40ba6a HTTP/2: rewritten handling of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6495
diff changeset
4278 r->stream->skip_data = 1;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4279
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4280 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
4281 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4282 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4283 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4284
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4285
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4286 ngx_int_t
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4287 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
4288 {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4289 size_t window;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4290 ngx_buf_t *buf;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4291 ngx_int_t rc;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4292 ngx_connection_t *fc;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4293 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
4294 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
4295 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
4296
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4297 stream = r->stream;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4298 fc = r->connection;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4299
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4300 if (fc->read->timedout) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4301 if (stream->recv_window) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4302 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4303 fc->timedout = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4304
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4305 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
4306 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4307
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4308 fc->read->timedout = 0;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4309 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4310
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4311 if (fc->error) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4312 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4313 return NGX_HTTP_BAD_REQUEST;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4314 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4315
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4316 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
4317
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4318 if (rc != NGX_OK) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4319 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4320 return rc;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4321 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4322
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4323 if (!r->request_body->rest) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4324 return NGX_OK;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4325 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4326
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4327 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
4328 return NGX_AGAIN;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4329 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4330
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4331 buf = r->request_body->buf;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4332
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4333 buf->pos = buf->start;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4334 buf->last = buf->start;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4335
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4336 window = buf->end - buf->start;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4337 h2c = stream->connection;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4338
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4339 if (h2c->state.stream == stream) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4340 window -= h2c->state.length;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4341 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4342
6566
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4343 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
4344 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
4345 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
4346 "http2 negative window update");
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4347 stream->skip_data = 1;
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4348 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
4349 }
ce94f07d5082 HTTP/2: implemented preread buffer for request body (closes #959).
Valentin Bartenev <vbart@nginx.com>
parents: 6520
diff changeset
4350
6497
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4351 return NGX_AGAIN;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4352 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4353
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4354 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
4355 window - stream->recv_window)
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4356 == NGX_ERROR)
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4357 {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4358 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4359 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
4360 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4361
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4362 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
4363 stream->skip_data = 1;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4364 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
4365 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4366
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4367 if (stream->recv_window == 0) {
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4368 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
4369 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
4370 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4371
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4372 stream->recv_window = window;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4373
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4374 return NGX_AGAIN;
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4375 }
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4376
9d66d7ed2abb HTTP/2: support for unbuffered upload of request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6496
diff changeset
4377
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4378 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4379 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
4380 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
4381 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4382 ngx_event_t *rev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4383 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4384
6588
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4385 if (stream->rst_sent) {
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4386 return NGX_OK;
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4387 }
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4388
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4389 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
4390 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4391 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4392 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4393 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4394
6495
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4395 stream->rst_sent = 1;
6588
dc5eaf998b96 HTTP/2: prevented double termination of a stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6587
diff changeset
4396 stream->skip_data = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4397
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4398 fc = stream->request->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4399 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4400
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4401 rev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4402 rev->handler(rev);
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 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4405 }
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4408 void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4409 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
4410 {
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4411 ngx_pool_t *pool;
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4412 ngx_uint_t push;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4413 ngx_event_t *ev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4414 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4415 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4416 ngx_http_v2_connection_t *h2c;
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 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4419 node = stream->node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4420
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4421 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
4422 "http2 close stream %ui, queued %ui, "
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4423 "processing %ui, pushing %ui",
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4424 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
4425
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4426 fc = stream->request->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4427
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4428 if (stream->queued) {
7610
82c1339e2637 HTTP/2: fixed socket leak with queued frames (ticket #1689).
Maxim Dounin <mdounin@mdounin.ru>
parents: 7571
diff changeset
4429 fc->error = 1;
7611
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4430 fc->write->handler = ngx_http_v2_retry_close_stream_handler;
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4431 fc->read->handler = ngx_http_v2_retry_close_stream_handler;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4432 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4433 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4434
6495
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4435 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
4436
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4437 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
4438 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
4439 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
4440 : 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
4441 != NGX_OK)
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4442 {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4443 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
4444 }
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4445
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4446 } else if (!stream->in_closed) {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4447 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
4448 != NGX_OK)
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4449 {
92464ebace8e HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
Valentin Bartenev <vbart@nginx.com>
parents: 6480
diff changeset
4450 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
4451 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4452 }
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
6410
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4455 if (h2c->state.stream == stream) {
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4456 h2c->state.stream = NULL;
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4457 }
c6ccc1ea9450 HTTP/2: cleaned up state while closing stream.
Valentin Bartenev <vbart@nginx.com>
parents: 6376
diff changeset
4458
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4459 push = stream->node->id % 2 == 0;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4460
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4461 node->stream = NULL;
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 ngx_queue_insert_tail(&h2c->closed, &node->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4464 h2c->closed_nodes++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4465
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4466 /*
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4467 * 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
4468 * 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
4469 *
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4470 * 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
4471 * 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
4472 */
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4473 pool = stream->pool;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4474
7548
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7547
diff changeset
4475 h2c->frames -= stream->frames;
99257b06b0bd HTTP/2: limited number of DATA frames.
Ruslan Ermilov <ru@nginx.com>
parents: 7547
diff changeset
4476
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4477 ngx_http_free_request(stream->request, rc);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4478
6411
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4479 if (pool != h2c->state.pool) {
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4480 ngx_destroy_pool(pool);
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4481
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4482 } else {
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4483 /* 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
4484 h2c->state.keep_pool = 0;
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4485 }
8ec349bb60b2 HTTP/2: always use temporary pool for processing headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6410
diff changeset
4486
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4487 ev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4488
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4489 if (ev->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4490 ngx_del_timer(ev);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4493 if (ev->posted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4494 ngx_delete_posted_event(ev);
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 ev = fc->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4498
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4499 if (ev->timer_set) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4500 ngx_del_timer(ev);
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 if (ev->posted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4504 ngx_delete_posted_event(ev);
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 fc->data = h2c->free_fake_connections;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4508 h2c->free_fake_connections = fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4509
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4510 if (push) {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4511 h2c->pushing--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4512
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4513 } else {
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4514 h2c->processing--;
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4515 }
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4516
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4517 if (h2c->processing || h2c->pushing || h2c->blocked) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4518 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4519 }
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 ev = h2c->connection->read;
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 ev->handler = ngx_http_v2_handle_connection_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4524 ngx_post_event(ev, &ngx_posted_events);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4527
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4528 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4529 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
4530 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4531 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4532 ngx_http_request_t *r;
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 fc = ev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4535 r = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4536
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4537 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
4538 "http2 close stream handler");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4539
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4540 if (ev->timedout) {
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4541 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
4542
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4543 fc->timedout = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4544
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4545 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
4546 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4547 }
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4548
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4549 ngx_http_v2_close_stream(r->stream, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4550 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4551
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 static void
7611
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4554 ngx_http_v2_retry_close_stream_handler(ngx_event_t *ev)
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4555 {
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4556 ngx_connection_t *fc;
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4557 ngx_http_request_t *r;
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4558
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4559 fc = ev->data;
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4560 r = fc->data;
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4561
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4562 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4563 "http2 retry close stream handler");
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4564
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4565 ngx_http_v2_close_stream(r->stream, 0);
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4566 }
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4567
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4568
8e64e11aaca0 HTTP/2: introduced separate handler to retry stream close.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7610
diff changeset
4569 static void
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4570 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
4571 {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4572 ngx_connection_t *c;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4573 ngx_http_v2_connection_t *h2c;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4574
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4575 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
4576 "http2 handle connection handler");
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4577
6957
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4578 c = rev->data;
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4579 h2c = c->data;
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4580
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4581 if (c->error) {
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4582 ngx_http_v2_finalize_connection(h2c, 0);
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4583 return;
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4584 }
83bae3d354ab HTTP/2: fixed connection finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6956
diff changeset
4585
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4586 rev->handler = ngx_http_v2_read_handler;
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 if (rev->ready) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4589 ngx_http_v2_read_handler(rev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4590 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4591 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4592
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4593 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
4594 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
4595 return;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4596 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4597
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4598 ngx_http_v2_handle_connection(c->data);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4602 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4603 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
4604 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4605 ngx_connection_t *c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4606 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4607 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4608
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4609 c = rev->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4610 h2c = c->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4611
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4612 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
4613
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4614 if (rev->timedout || c->close) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4615 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
4616 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4617 }
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 #if (NGX_HAVE_KQUEUE)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4620
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4621 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4622 if (rev->pending_eof) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4623 c->log->handler = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4624 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
4625 "kevent() reported that client %V closed "
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4626 "idle connection", &c->addr_text);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4627 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4628 if (c->ssl) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4629 c->ssl->no_send_shutdown = 1;
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 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4632 ngx_http_close_connection(c);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4633 return;
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 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4636
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4637 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4638
7378
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4639 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4640 ngx_http_v2_module);
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4641
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4642 if (h2c->idle++ > 10 * h2scf->max_requests) {
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4643 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4644 "http2 flood detected");
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4645 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4646 return;
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4647 }
e7f19d268c72 HTTP/2: limit the number of idle state switches.
Ruslan Ermilov <ru@nginx.com>
parents: 7377
diff changeset
4648
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4649 c->destroyed = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4650 ngx_reusable_connection(c, 0);
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 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
4653 if (h2c->pool == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4654 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
4655 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4656 }
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 c->write->handler = ngx_http_v2_write_handler;
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 rev->handler = ngx_http_v2_read_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4661 ngx_http_v2_read_handler(rev);
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4664
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4665 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4666 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
4667 ngx_uint_t status)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4668 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4669 ngx_uint_t i, size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4670 ngx_event_t *ev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4671 ngx_connection_t *c, *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4672 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4673 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4674 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4675 ngx_http_v2_srv_conf_t *h2scf;
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 c = h2c->connection;
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 h2c->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4680
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
4681 if (!c->error && !h2c->goaway) {
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4682 h2c->goaway = 1;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4683
6778
5e95b9fb33b7 HTTP/2: graceful shutdown of active connections (closes #1106).
Valentin Bartenev <vbart@nginx.com>
parents: 6732
diff changeset
4684 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
4685 (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
4686 }
6246
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
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4689 if (!h2c->processing && !h2c->pushing) {
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4690 goto done;
6246
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
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4693 c->read->handler = ngx_http_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4694 c->write->handler = ngx_http_empty_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4695
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4696 h2c->last_out = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4697
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4698 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
4699 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4700
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4701 size = ngx_http_v2_index_size(h2scf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4702
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4703 for (i = 0; i < size; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4704
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4705 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
4706 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4707
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4708 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4709 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4710 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4711
6833
3834951e32ab HTTP/2: fixed posted streams handling.
Valentin Bartenev <vbart@nginx.com>
parents: 6805
diff changeset
4712 stream->waiting = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4713
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4714 r = stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4715 fc = r->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4716
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4717 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4718
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4719 if (stream->queued) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4720 stream->queued = 0;
6956
9b5f31fdb850 HTTP/2: fixed stream finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6955
diff changeset
4721
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4722 ev = fc->write;
6956
9b5f31fdb850 HTTP/2: fixed stream finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6955
diff changeset
4723 ev->active = 0;
9b5f31fdb850 HTTP/2: fixed stream finalization.
Valentin Bartenev <vbart@nginx.com>
parents: 6955
diff changeset
4724 ev->ready = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4725
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4726 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4727 ev = fc->read;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4728 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4729
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4730 ev->eof = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4731 ev->handler(ev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4732 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4733 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4734
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4735 h2c->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4736
7201
641306096f5b HTTP/2: server push.
Ruslan Ermilov <ru@nginx.com>
parents: 7200
diff changeset
4737 if (h2c->processing || h2c->pushing) {
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4738 c->error = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4739 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4740 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4741
7673
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4742 done:
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4743
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4744 if (c->error) {
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4745 ngx_http_close_connection(c);
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4746 return;
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4747 }
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4748
c5840ca2063d HTTP/2: lingering close after GOAWAY.
Ruslan Ermilov <ru@nginx.com>
parents: 7656
diff changeset
4749 ngx_http_v2_lingering_close(h2c);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4750 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4751
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4752
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4753 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4754 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
4755 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4756 ngx_uint_t i, size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4757 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4758 ngx_http_v2_node_t *node;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4759 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4760 ngx_http_v2_srv_conf_t *h2scf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4761
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4762 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
4763 ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4764
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4765 size = ngx_http_v2_index_size(h2scf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4766
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4767 for (i = 0; i < size; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4768
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4769 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
4770 stream = node->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4771
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4772 if (stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4773 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4774 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4775
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4776 if (delta > 0
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4777 && stream->send_window
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4778 > (ssize_t) (NGX_HTTP_V2_MAX_WINDOW - delta))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4779 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4780 if (ngx_http_v2_terminate_stream(h2c, stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4781 NGX_HTTP_V2_FLOW_CTRL_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4782 == NGX_ERROR)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4783 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4784 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4785 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4786
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4787 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4788 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4789
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4790 stream->send_window += delta;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4791
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4792 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
4793 "http2:%ui adjusted window: %z",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4794 node->id, stream->send_window);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4795
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4796 if (stream->send_window > 0 && stream->exhausted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4797 stream->exhausted = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4798
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4799 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4800
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4801 wev->active = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4802 wev->ready = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4803
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6411
diff changeset
4804 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4805 wev->handler(wev);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4806 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4807 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4808 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4809 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4810
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4811 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4812 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4813
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4814
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4815 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4816 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
4817 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
4818 {
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4819 ngx_queue_t *children, *q;
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4820 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
4821
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4822 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
4823
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4824 if (parent == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4825 parent = NGX_HTTP_V2_ROOT;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4826
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4827 if (depend != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4828 exclusive = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4829 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4830
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4831 node->rank = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4832 node->rel_weight = (1.0 / 256) * node->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4833
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4834 children = &h2c->dependencies;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4835
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4836 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4837 if (node->parent != NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4838
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4839 for (next = parent->parent;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4840 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
4841 next = next->parent)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4842 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4843 if (next != node) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4844 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4845 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4846
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4847 ngx_queue_remove(&parent->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4848 ngx_queue_insert_after(&node->queue, &parent->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4849
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4850 parent->parent = node->parent;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4851
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4852 if (node->parent == NGX_HTTP_V2_ROOT) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4853 parent->rank = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4854 parent->rel_weight = (1.0 / 256) * parent->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4855
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4856 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4857 parent->rank = node->parent->rank + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4858 parent->rel_weight = (node->parent->rel_weight / 256)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4859 * parent->weight;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4860 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4861
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4862 if (!exclusive) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4863 ngx_http_v2_node_children_update(parent);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4864 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4865
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4866 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4867 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4868 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4869
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4870 node->rank = parent->rank + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4871 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
4872
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4873 if (parent->stream == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4874 ngx_queue_remove(&parent->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4875 ngx_queue_insert_tail(&h2c->closed, &parent->reuse);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4876 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4877
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4878 children = &parent->children;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4879 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4880
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4881 if (exclusive) {
6272
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4882 for (q = ngx_queue_head(children);
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4883 q != ngx_queue_sentinel(children);
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4884 q = ngx_queue_next(q))
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4885 {
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4886 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
4887 child->parent = node;
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4888 }
b6a665bf858a HTTP/2: fix indirect reprioritization.
Piotr Sikora <piotrsikora@google.com>
parents: 6271
diff changeset
4889
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4890 ngx_queue_add(&node->children, children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4891 ngx_queue_init(children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4892 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4893
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4894 if (node->parent != NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4895 ngx_queue_remove(&node->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4896 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4897
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4898 ngx_queue_insert_tail(children, &node->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4899
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4900 node->parent = parent;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4901
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4902 ngx_http_v2_node_children_update(node);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4903 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4904
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4905
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4906 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4907 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
4908 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4909 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4910 ngx_http_v2_node_t *child;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4911
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4912 for (q = ngx_queue_head(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4913 q != ngx_queue_sentinel(&node->children);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4914 q = ngx_queue_next(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4915 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4916 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
4917
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4918 child->rank = node->rank + 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4919 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
4920
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4921 ngx_http_v2_node_children_update(child);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4922 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4923 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4924
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4925
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4926 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4927 ngx_http_v2_pool_cleanup(void *data)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4928 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4929 ngx_http_v2_connection_t *h2c = data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4930
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4931 if (h2c->state.pool) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4932 ngx_destroy_pool(h2c->state.pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4933 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4934
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4935 if (h2c->pool) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4936 ngx_destroy_pool(h2c->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4937 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4938 }