annotate src/http/v3/ngx_http_v3_request.c @ 8548:9ffef6054abf quic

HTTP/3: fixed handling request body eof. While for HTTP/1 unexpected eof always means an error, for HTTP/3 an eof right after a DATA frame end means the end of the request body. For this reason, since adding HTTP/3 support, eof no longer produced an error right after recv() but was passed to filters which would make a decision. This decision was made in ngx_http_parse_chunked() and ngx_http_v3_parse_request_body() based on the b->last_buf flag. Now that since 0f7f1a509113 (1.19.2) rb->chunked->length is a lower threshold for the expected number of bytes, it can be set to zero to indicate that more bytes may or may not follow. Now it's possible to move the check for eof from parser functions to ngx_http_request_body_chunked_filter() and clean up the parsing code. Also, in the default branch, in case of eof, the following three things happened, which were replaced with returning NGX_ERROR while implementing HTTP/3: - "client prematurely closed connection" message was logged - c->error flag was set - NGX_HTTP_BAD_REQUEST was returned The change brings back this behavior for HTTP/1 as well as HTTP/3.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 16 Sep 2020 18:59:25 +0100
parents 830680e78b24
children d70a38acaea0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
1
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
2 /*
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
3 * Copyright (C) Roman Arutyunyan
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
5 */
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
6
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
7
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
10 #include <ngx_http.h>
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
11
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
12
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
13 /* static table indices */
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
14 #define NGX_HTTP_V3_HEADER_AUTHORITY 0
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
15 #define NGX_HTTP_V3_HEADER_PATH_ROOT 1
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
16 #define NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO 4
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
17 #define NGX_HTTP_V3_HEADER_DATE 6
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
18 #define NGX_HTTP_V3_HEADER_LAST_MODIFIED 10
8489
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
19 #define NGX_HTTP_V3_HEADER_LOCATION 12
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
20 #define NGX_HTTP_V3_HEADER_METHOD_GET 17
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
21 #define NGX_HTTP_V3_HEADER_SCHEME_HTTP 22
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
22 #define NGX_HTTP_V3_HEADER_SCHEME_HTTPS 23
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
23 #define NGX_HTTP_V3_HEADER_STATUS_200 25
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
24 #define NGX_HTTP_V3_HEADER_ACCEPT_ENCODING 31
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
25 #define NGX_HTTP_V3_HEADER_CONTENT_TYPE_TEXT_PLAIN 53
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
26 #define NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING 59
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
27 #define NGX_HTTP_V3_HEADER_ACCEPT_LANGUAGE 72
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
28 #define NGX_HTTP_V3_HEADER_SERVER 92
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
29 #define NGX_HTTP_V3_HEADER_USER_AGENT 95
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
30
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
31
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
32 static ngx_int_t ngx_http_v3_process_pseudo_header(ngx_http_request_t *r,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
33 ngx_str_t *name, ngx_str_t *value);
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
34 static ngx_int_t ngx_http_v3_push_resources(ngx_http_request_t *r,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
35 ngx_chain_t ***out);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
36 static ngx_int_t ngx_http_v3_push_resource(ngx_http_request_t *r,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
37 ngx_str_t *path, ngx_chain_t ***out);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
38 static ngx_int_t ngx_http_v3_create_push_request(
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
39 ngx_http_request_t *pr, ngx_str_t *path, uint64_t push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
40 static ngx_int_t ngx_http_v3_set_push_header(ngx_http_request_t *r,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
41 const char *name, ngx_str_t *value);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
42 static void ngx_http_v3_push_request_handler(ngx_event_t *ev);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
43 static ngx_chain_t *ngx_http_v3_create_push_promise(ngx_http_request_t *r,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
44 ngx_str_t *path, uint64_t push_id);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
45
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
46
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
47 struct {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
48 ngx_str_t name;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
49 ngx_uint_t method;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
50 } ngx_http_v3_methods[] = {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
51
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
52 { ngx_string("GET"), NGX_HTTP_GET },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
53 { ngx_string("POST"), NGX_HTTP_POST },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
54 { ngx_string("HEAD"), NGX_HTTP_HEAD },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
55 { ngx_string("OPTIONS"), NGX_HTTP_OPTIONS },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
56 { ngx_string("PROPFIND"), NGX_HTTP_PROPFIND },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
57 { ngx_string("PUT"), NGX_HTTP_PUT },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
58 { ngx_string("MKCOL"), NGX_HTTP_MKCOL },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
59 { ngx_string("DELETE"), NGX_HTTP_DELETE },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
60 { ngx_string("COPY"), NGX_HTTP_COPY },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
61 { ngx_string("MOVE"), NGX_HTTP_MOVE },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
62 { ngx_string("PROPPATCH"), NGX_HTTP_PROPPATCH },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
63 { ngx_string("LOCK"), NGX_HTTP_LOCK },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
64 { ngx_string("UNLOCK"), NGX_HTTP_UNLOCK },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
65 { ngx_string("PATCH"), NGX_HTTP_PATCH },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
66 { ngx_string("TRACE"), NGX_HTTP_TRACE }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
67 };
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
68
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
69
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
70 ngx_int_t
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
71 ngx_http_v3_parse_request(ngx_http_request_t *r, ngx_buf_t *b)
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
72 {
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
73 size_t len;
8233
1e45c02f6376 HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8230
diff changeset
74 u_char *p;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
75 ngx_int_t rc, n;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
76 ngx_str_t *name, *value;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
77 ngx_connection_t *c;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
78 ngx_http_v3_parse_headers_t *st;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
79
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
80 c = r->connection;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
81 st = r->h3_parse;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
82
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
83 if (st == NULL) {
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
84 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header");
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
85
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
86 st = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_parse_headers_t));
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
87 if (st == NULL) {
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
88 goto failed;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
89 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
90
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
91 r->h3_parse = st;
8407
d6feece1288a Fixed $request_length for HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8406
diff changeset
92 r->parse_start = b->pos;
8408
5b367070cc9c Fixed client buffer reallocation for HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8407
diff changeset
93 r->state = 1;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
94 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
95
8230
31f7c697b6d9 Fixed pointer increment while parsing HTTP/3 header.
Roman Arutyunyan <arut@nginx.com>
parents: 8226
diff changeset
96 while (b->pos < b->last) {
8456
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
97 rc = ngx_http_v3_parse_headers(c, st, *b->pos);
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
98
8460
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
99 if (rc > 0) {
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
100 ngx_http_v3_finalize_connection(c, rc,
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
101 "could not parse request headers");
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
102 goto failed;
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
103 }
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
104
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
105 if (rc == NGX_ERROR) {
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
106 goto failed;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
107 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
108
8456
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
109 if (rc == NGX_BUSY) {
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
110 return NGX_BUSY;
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
111 }
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
112
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
113 b->pos++;
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
114
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
115 if (rc == NGX_AGAIN) {
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
116 continue;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
117 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
118
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
119 name = &st->header_rep.header.name;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
120 value = &st->header_rep.header.value;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
121
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
122 n = ngx_http_v3_process_pseudo_header(r, name, value);
8233
1e45c02f6376 HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8230
diff changeset
123
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
124 if (n == NGX_ERROR) {
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
125 goto failed;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
126 }
8233
1e45c02f6376 HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8230
diff changeset
127
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
128 if (n == NGX_OK && rc == NGX_OK) {
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
129 continue;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
130 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
131
8494
e334ca1b23ba HTTP/3: support $server_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8490
diff changeset
132 ngx_str_set(&r->http_protocol, "HTTP/3.0");
e334ca1b23ba HTTP/3: support $server_protocol variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8490
diff changeset
133
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
134 len = (r->method_end - r->method_start) + 1
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
135 + (r->uri_end - r->uri_start) + 1
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
136 + sizeof("HTTP/3") - 1;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
137
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
138 p = ngx_pnalloc(c->pool, len);
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
139 if (p == NULL) {
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
140 goto failed;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
141 }
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
142
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
143 r->request_start = p;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
144
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
145 p = ngx_cpymem(p, r->method_start, r->method_end - r->method_start);
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
146 *p++ = ' ';
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
147 p = ngx_cpymem(p, r->uri_start, r->uri_end - r->uri_start);
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
148 *p++ = ' ';
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
149 p = ngx_cpymem(p, "HTTP/3", sizeof("HTTP/3") - 1);
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
150
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
151 r->request_end = p;
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
152 r->state = 0;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
153
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
154 return NGX_OK;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
155 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
156
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
157 return NGX_AGAIN;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
158
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
159 failed:
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
160
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
161 return NGX_HTTP_PARSE_INVALID_REQUEST;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
162 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
163
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
164
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
165 ngx_int_t
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
166 ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b,
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
167 ngx_uint_t allow_underscores)
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
168 {
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
169 u_char ch;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
170 ngx_int_t rc;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
171 ngx_str_t *name, *value;
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
172 ngx_uint_t hash, i, n;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
173 ngx_connection_t *c;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
174 ngx_http_v3_parse_headers_t *st;
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
175 enum {
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
176 sw_start = 0,
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
177 sw_done,
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
178 sw_next,
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
179 sw_header
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
180 };
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
181
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
182 c = r->connection;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
183 st = r->h3_parse;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
184
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
185 switch (r->state) {
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
186
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
187 case sw_start:
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
188 r->parse_start = b->pos;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
189
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
190 if (st->state) {
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
191 r->state = sw_next;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
192 goto done;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
193 }
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
194
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
195 name = &st->header_rep.header.name;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
196
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
197 if (name->len && name->data[0] != ':') {
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
198 r->state = sw_done;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
199 goto done;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
200 }
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
201
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
202 /* fall through */
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
203
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
204 case sw_done:
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
205 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
206 "http3 parse header done");
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
207 return NGX_HTTP_PARSE_HEADER_DONE;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
208
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
209 case sw_next:
8407
d6feece1288a Fixed $request_length for HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8406
diff changeset
210 r->parse_start = b->pos;
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
211 r->invalid_header = 0;
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
212 break;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
213
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
214 case sw_header:
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
215 break;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
216 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
217
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
218 while (b->pos < b->last) {
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
219 rc = ngx_http_v3_parse_headers(c, st, *b->pos++);
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
220
8460
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
221 if (rc > 0) {
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
222 ngx_http_v3_finalize_connection(c, rc,
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
223 "could not parse request headers");
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
224 return NGX_HTTP_PARSE_INVALID_HEADER;
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
225 }
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
226
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
227 if (rc == NGX_ERROR) {
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
228 return NGX_HTTP_PARSE_INVALID_HEADER;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
229 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
230
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
231 if (rc == NGX_DONE) {
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
232 r->state = sw_done;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
233 goto done;
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
234 }
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
235
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
236 if (rc == NGX_OK) {
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
237 r->state = sw_next;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
238 goto done;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
239 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
240 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
241
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
242 r->state = sw_header;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
243 return NGX_AGAIN;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
244
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
245 done:
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
246
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
247 name = &st->header_rep.header.name;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
248 value = &st->header_rep.header.value;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
249
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
250 r->header_name_start = name->data;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
251 r->header_name_end = name->data + name->len;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
252 r->header_start = value->data;
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
253 r->header_end = value->data + value->len;
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
254
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
255 hash = 0;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
256 i = 0;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
257
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
258 for (n = 0; n < name->len; n++) {
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
259 ch = name->data[n];
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
260
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
261 if (ch >= 'A' && ch <= 'Z') {
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
262 /*
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
263 * A request or response containing uppercase
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
264 * header field names MUST be treated as malformed
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
265 */
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
266 return NGX_HTTP_PARSE_INVALID_HEADER;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
267 }
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
268
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
269 if (ch == '\0') {
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
270 return NGX_HTTP_PARSE_INVALID_HEADER;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
271 }
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
272
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
273 if (ch == '_' && !allow_underscores) {
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
274 r->invalid_header = 1;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
275 continue;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
276 }
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
277
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
278 if ((ch < 'a' || ch > 'z')
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
279 && (ch < '0' || ch > '9')
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
280 && ch != '-' && ch != '_')
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
281 {
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
282 r->invalid_header = 1;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
283 continue;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
284 }
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
285
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
286 hash = ngx_hash(hash, ch);
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
287 r->lowcase_header[i++] = ch;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
288 i &= (NGX_HTTP_LC_HEADER_LEN - 1);
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
289 }
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
290
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
291 r->header_hash = hash;
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
292 r->lowcase_index = i;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
293
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
294 return NGX_OK;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
295 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
296
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
297
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
298 static ngx_int_t
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
299 ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
300 ngx_str_t *value)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
301 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
302 ngx_uint_t i;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
303 ngx_connection_t *c;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
304
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
305 if (name->len == 0 || name->data[0] != ':') {
8233
1e45c02f6376 HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8230
diff changeset
306 return NGX_DONE;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
307 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
308
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
309 c = r->connection;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
310
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
311 if (name->len == 7 && ngx_strncmp(name->data, ":method", 7) == 0) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
312 r->method_start = value->data;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
313 r->method_end = value->data + value->len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
314
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
315 for (i = 0; i < sizeof(ngx_http_v3_methods)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
316 / sizeof(ngx_http_v3_methods[0]); i++)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
317 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
318 if (value->len == ngx_http_v3_methods[i].name.len
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
319 && ngx_strncmp(value->data, ngx_http_v3_methods[i].name.data,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
320 value->len) == 0)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
321 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
322 r->method = ngx_http_v3_methods[i].method;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
323 break;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
324 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
325 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
326
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
327 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
328 "http3 method \"%V\" %ui", value, r->method);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
329 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
330 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
331
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
332 if (name->len == 5 && ngx_strncmp(name->data, ":path", 5) == 0) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
333 r->uri_start = value->data;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
334 r->uri_end = value->data + value->len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
335
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
336 if (ngx_http_parse_uri(r) != NGX_OK) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
337 ngx_log_error(NGX_LOG_INFO, c->log, 0,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
338 "client sent invalid :path header: \"%V\"", value);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
339 return NGX_ERROR;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
340 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
341
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
342 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
343 "http3 path \"%V\"", value);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
344
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
345 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
346 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
347
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
348 if (name->len == 7 && ngx_strncmp(name->data, ":scheme", 7) == 0) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
349 r->schema_start = value->data;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
350 r->schema_end = value->data + value->len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
351
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
352 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
353 "http3 schema \"%V\"", value);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
354
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
355 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
356 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
357
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
358 if (name->len == 10 && ngx_strncmp(name->data, ":authority", 10) == 0) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
359 r->host_start = value->data;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
360 r->host_end = value->data + value->len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
361
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
362 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
363 "http3 authority \"%V\"", value);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
364
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
365 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
366 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
367
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
368 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
369 "http3 unknown pseudo header \"%V\" \"%V\"", name, value);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
370
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
371 return NGX_OK;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
372 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
373
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
374
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
375 ngx_int_t
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
376 ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b,
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
377 ngx_http_chunked_t *ctx)
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
378 {
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
379 ngx_int_t rc;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
380 ngx_connection_t *c;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
381 ngx_http_v3_parse_data_t *st;
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
382 enum {
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
383 sw_start = 0,
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
384 sw_skip
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
385 };
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
386
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
387 c = r->connection;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
388 st = ctx->h3_parse;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
389
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
390 if (st == NULL) {
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
391 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
392 "http3 parse request body");
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
393
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
394 st = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_parse_data_t));
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
395 if (st == NULL) {
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
396 goto failed;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
397 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
398
8511
830680e78b24 HTTP/3: fixed context storage in request body parser.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8497
diff changeset
399 ctx->h3_parse = st;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
400 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
401
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
402 while (b->pos < b->last && ctx->size == 0) {
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
403
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
404 rc = ngx_http_v3_parse_data(c, st, *b->pos++);
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
405
8460
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
406 if (rc > 0) {
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
407 ngx_http_v3_finalize_connection(c, rc,
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
408 "could not parse request body");
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
409 goto failed;
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
410 }
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
411
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
412 if (rc == NGX_ERROR) {
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
413 goto failed;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
414 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
415
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
416 if (rc == NGX_AGAIN) {
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
417 ctx->state = sw_skip;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
418 continue;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
419 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
420
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
421 /* rc == NGX_DONE */
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
422
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
423 ctx->size = st->length;
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
424 ctx->state = sw_start;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
425 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
426
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
427 if (ctx->state == sw_skip) {
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
428 ctx->length = 1;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
429 return NGX_AGAIN;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
430 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
431
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
432 if (b->pos == b->last) {
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
433 ctx->length = ctx->size;
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
434 return NGX_AGAIN;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
435 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
436
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
437 return NGX_OK;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
438
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
439 failed:
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
440
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
441 return NGX_ERROR;
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
442 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
443
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
444
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
445 ngx_chain_t *
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
446 ngx_http_v3_create_header(ngx_http_request_t *r)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
447 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
448 u_char *p;
8253
69365c7bb07f Removed unused variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8238
diff changeset
449 size_t len, n;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
450 ngx_buf_t *b;
8489
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
451 ngx_str_t host;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
452 ngx_uint_t i, port;
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
453 ngx_chain_t *out, *hl, *cl, **ll;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
454 ngx_list_part_t *part;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
455 ngx_table_elt_t *header;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
456 ngx_connection_t *c;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
457 ngx_http_core_loc_conf_t *clcf;
8489
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
458 ngx_http_core_srv_conf_t *cscf;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
459 u_char addr[NGX_SOCKADDR_STRLEN];
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
460
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
461 c = r->connection;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
462
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
463 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header");
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
464
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
465 out = NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
466 ll = &out;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
467
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
468 if ((c->qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
469 && r->method != NGX_HTTP_HEAD)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
470 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
471 if (ngx_http_v3_push_resources(r, &ll) != NGX_OK) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
472 return NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
473 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
474 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
475
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
476 len = ngx_http_v3_encode_header_block_prefix(NULL, 0, 0, 0);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
477
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
478 if (r->headers_out.status == NGX_HTTP_OK) {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
479 len += ngx_http_v3_encode_header_ri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
480 NGX_HTTP_V3_HEADER_STATUS_200);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
481
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
482 } else {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
483 len += ngx_http_v3_encode_header_lri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
484 NGX_HTTP_V3_HEADER_STATUS_200,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
485 NULL, 3);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
486 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
487
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
488 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
489
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
490 if (r->headers_out.server == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
491 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
492 n = sizeof(NGINX_VER) - 1;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
493
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
494 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
495 n = sizeof(NGINX_VER_BUILD) - 1;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
496
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
497 } else {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
498 n = sizeof("nginx") - 1;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
499 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
500
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
501 len += ngx_http_v3_encode_header_lri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
502 NGX_HTTP_V3_HEADER_SERVER,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
503 NULL, n);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
504 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
505
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
506 if (r->headers_out.date == NULL) {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
507 len += ngx_http_v3_encode_header_lri(NULL, 0, NGX_HTTP_V3_HEADER_DATE,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
508 NULL, ngx_cached_http_time.len);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
509 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
510
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
511 if (r->headers_out.content_type.len) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
512 n = r->headers_out.content_type.len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
513
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
514 if (r->headers_out.content_type_len == r->headers_out.content_type.len
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
515 && r->headers_out.charset.len)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
516 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
517 n += sizeof("; charset=") - 1 + r->headers_out.charset.len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
518 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
519
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
520 len += ngx_http_v3_encode_header_lri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
521 NGX_HTTP_V3_HEADER_CONTENT_TYPE_TEXT_PLAIN,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
522 NULL, n);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
523 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
524
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
525 if (r->headers_out.content_length == NULL) {
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
526 if (r->headers_out.content_length_n > 0) {
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
527 len += ngx_http_v3_encode_header_lri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
528 NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
529 NULL, NGX_OFF_T_LEN);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
530
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
531 } else if (r->headers_out.content_length_n == 0) {
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
532 len += ngx_http_v3_encode_header_ri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
533 NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO);
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
534 }
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
535 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
536
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
537 if (r->headers_out.last_modified == NULL
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
538 && r->headers_out.last_modified_time != -1)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
539 {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
540 len += ngx_http_v3_encode_header_lri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
541 NGX_HTTP_V3_HEADER_LAST_MODIFIED, NULL,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
542 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
543 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
544
8489
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
545 if (r->headers_out.location
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
546 && r->headers_out.location->value.len
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
547 && r->headers_out.location->value.data[0] == '/'
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
548 && clcf->absolute_redirect)
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
549 {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
550 r->headers_out.location->hash = 0;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
551
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
552 if (clcf->server_name_in_redirect) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
553 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
554 host = cscf->server_name;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
555
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
556 } else if (r->headers_in.server.len) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
557 host = r->headers_in.server;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
558
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
559 } else {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
560 host.len = NGX_SOCKADDR_STRLEN;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
561 host.data = addr;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
562
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
563 if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
564 return NULL;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
565 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
566 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
567
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
568 port = ngx_inet_get_port(c->local_sockaddr);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
569
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
570 n = sizeof("https://") - 1 + host.len
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
571 + r->headers_out.location->value.len;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
572
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
573 if (clcf->port_in_redirect) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
574 port = (port == 443) ? 0 : port;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
575
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
576 } else {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
577 port = 0;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
578 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
579
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
580 if (port) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
581 n += sizeof(":65535") - 1;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
582 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
583
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
584 len += ngx_http_v3_encode_header_lri(NULL, 0,
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
585 NGX_HTTP_V3_HEADER_LOCATION, NULL, n);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
586
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
587 } else {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
588 ngx_str_null(&host);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
589 port = 0;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
590 }
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
591
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
592 #if (NGX_HTTP_GZIP)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
593 if (r->gzip_vary) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
594 if (clcf->gzip_vary) {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
595 len += ngx_http_v3_encode_header_ri(NULL, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
596 NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
597
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
598 } else {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
599 r->gzip_vary = 0;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
600 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
601 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
602 #endif
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
603
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
604 part = &r->headers_out.headers.part;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
605 header = part->elts;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
606
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
607 for (i = 0; /* void */; i++) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
608
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
609 if (i >= part->nelts) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
610 if (part->next == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
611 break;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
612 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
613
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
614 part = part->next;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
615 header = part->elts;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
616 i = 0;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
617 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
618
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
619 if (header[i].hash == 0) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
620 continue;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
621 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
622
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
623 len += ngx_http_v3_encode_header_l(NULL, &header[i].key,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
624 &header[i].value);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
625 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
626
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
627 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 header len:%uz", len);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
628
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
629 b = ngx_create_temp_buf(r->pool, len);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
630 if (b == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
631 return NULL;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
632 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
633
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
634 b->last = (u_char *) ngx_http_v3_encode_header_block_prefix(b->last,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
635 0, 0, 0);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
636
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
637 if (r->headers_out.status == NGX_HTTP_OK) {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
638 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
639 NGX_HTTP_V3_HEADER_STATUS_200);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
640
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
641 } else {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
642 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
643 NGX_HTTP_V3_HEADER_STATUS_200,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
644 NULL, 3);
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
645 b->last = ngx_sprintf(b->last, "%03ui", r->headers_out.status);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
646 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
647
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
648 if (r->headers_out.server == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
649 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
650 p = (u_char *) NGINX_VER;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
651 n = sizeof(NGINX_VER) - 1;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
652
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
653 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
654 p = (u_char *) NGINX_VER_BUILD;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
655 n = sizeof(NGINX_VER_BUILD) - 1;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
656
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
657 } else {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
658 p = (u_char *) "nginx";
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
659 n = sizeof("nginx") - 1;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
660 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
661
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
662 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
663 NGX_HTTP_V3_HEADER_SERVER,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
664 p, n);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
665 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
666
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
667 if (r->headers_out.date == NULL) {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
668 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
669 NGX_HTTP_V3_HEADER_DATE,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
670 ngx_cached_http_time.data,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
671 ngx_cached_http_time.len);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
672 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
673
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
674 if (r->headers_out.content_type.len) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
675 n = r->headers_out.content_type.len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
676
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
677 if (r->headers_out.content_type_len == r->headers_out.content_type.len
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
678 && r->headers_out.charset.len)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
679 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
680 n += sizeof("; charset=") - 1 + r->headers_out.charset.len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
681 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
682
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
683 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
684 NGX_HTTP_V3_HEADER_CONTENT_TYPE_TEXT_PLAIN,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
685 NULL, n);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
686
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
687 p = b->last;
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
688 b->last = ngx_cpymem(b->last, r->headers_out.content_type.data,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
689 r->headers_out.content_type.len);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
690
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
691 if (r->headers_out.content_type_len == r->headers_out.content_type.len
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
692 && r->headers_out.charset.len)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
693 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
694 b->last = ngx_cpymem(b->last, "; charset=",
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
695 sizeof("; charset=") - 1);
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
696 b->last = ngx_cpymem(b->last, r->headers_out.charset.data,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
697 r->headers_out.charset.len);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
698
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
699 /* update r->headers_out.content_type for possible logging */
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
700
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
701 r->headers_out.content_type.len = b->last - p;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
702 r->headers_out.content_type.data = p;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
703 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
704 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
705
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
706 if (r->headers_out.content_length == NULL) {
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
707 if (r->headers_out.content_length_n > 0) {
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
708 p = ngx_sprintf(b->last, "%O", r->headers_out.content_length_n);
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
709 n = p - b->last;
8238
a3257a725b3d Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8233
diff changeset
710
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
711 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
712 NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
713 NULL, n);
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
714
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
715 b->last = ngx_sprintf(b->last, "%O",
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
716 r->headers_out.content_length_n);
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
717
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
718 } else if (r->headers_out.content_length_n == 0) {
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
719 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
720 NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO);
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
721 }
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
722 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
723
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
724 if (r->headers_out.last_modified == NULL
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
725 && r->headers_out.last_modified_time != -1)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
726 {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
727 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
728 NGX_HTTP_V3_HEADER_LAST_MODIFIED, NULL,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
729 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
730
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
731 b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
732 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
733
8489
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
734 if (host.data) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
735 n = sizeof("https://") - 1 + host.len
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
736 + r->headers_out.location->value.len;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
737
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
738 if (port) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
739 n += ngx_sprintf(b->last, ":%ui", port) - b->last;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
740 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
741
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
742 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
743 NGX_HTTP_V3_HEADER_LOCATION,
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
744 NULL, n);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
745
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
746 p = b->last;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
747 b->last = ngx_cpymem(b->last, "https://", sizeof("https://") - 1);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
748 b->last = ngx_cpymem(b->last, host.data, host.len);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
749
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
750 if (port) {
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
751 b->last = ngx_sprintf(b->last, ":%ui", port);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
752 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
753
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
754 b->last = ngx_cpymem(b->last, r->headers_out.location->value.data,
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
755 r->headers_out.location->value.len);
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
756
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
757 /* update r->headers_out.location->value for possible logging */
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
758
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
759 r->headers_out.location->value.len = b->last - p;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
760 r->headers_out.location->value.data = p;
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
761 ngx_str_set(&r->headers_out.location->key, "Location");
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
762 }
5d2e285677a7 HTTP/3: generate Location response header for absolute redirects.
Roman Arutyunyan <arut@nginx.com>
parents: 8488
diff changeset
763
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
764 #if (NGX_HTTP_GZIP)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
765 if (r->gzip_vary) {
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
766 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
767 NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
768 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
769 #endif
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
770
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
771 part = &r->headers_out.headers.part;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
772 header = part->elts;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
773
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
774 for (i = 0; /* void */; i++) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
775
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
776 if (i >= part->nelts) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
777 if (part->next == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
778 break;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
779 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
780
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
781 part = part->next;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
782 header = part->elts;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
783 i = 0;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
784 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
785
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
786 if (header[i].hash == 0) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
787 continue;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
788 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
789
8488
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
790 b->last = (u_char *) ngx_http_v3_encode_header_l(b->last,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
791 &header[i].key,
79125ef2e39f HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8460
diff changeset
792 &header[i].value);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
793 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
794
8238
a3257a725b3d Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8233
diff changeset
795 if (r->header_only) {
a3257a725b3d Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8233
diff changeset
796 b->last_buf = 1;
a3257a725b3d Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8233
diff changeset
797 }
a3257a725b3d Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8233
diff changeset
798
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
799 cl = ngx_alloc_chain_link(c->pool);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
800 if (cl == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
801 return NULL;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
802 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
803
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
804 cl->buf = b;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
805 cl->next = NULL;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
806
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
807 n = b->last - b->pos;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
808
8490
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
809 len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_HEADERS)
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
810 + ngx_http_v3_encode_varlen_int(NULL, n);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
811
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
812 b = ngx_create_temp_buf(c->pool, len);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
813 if (b == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
814 return NULL;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
815 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
816
8490
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
817 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last,
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
818 NGX_HTTP_V3_FRAME_HEADERS);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
819 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, n);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
820
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
821 hl = ngx_alloc_chain_link(c->pool);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
822 if (hl == NULL) {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
823 return NULL;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
824 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
825
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
826 hl->buf = b;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
827 hl->next = cl;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
828
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
829 *ll = hl;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
830 ll = &cl->next;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
831
8451
908cae4f3078 HTTP/3: do not emit a DATA frame header for header_only responses.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8408
diff changeset
832 if (r->headers_out.content_length_n >= 0 && !r->header_only) {
8490
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
833 len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_DATA)
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
834 + ngx_http_v3_encode_varlen_int(NULL,
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
835 r->headers_out.content_length_n);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
836
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
837 b = ngx_create_temp_buf(c->pool, len);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
838 if (b == NULL) {
8394
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8329
diff changeset
839 return NULL;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
840 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
841
8490
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
842 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last,
e24f7b50ba1d HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Roman Arutyunyan <arut@nginx.com>
parents: 8489
diff changeset
843 NGX_HTTP_V3_FRAME_DATA);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
844 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
845 r->headers_out.content_length_n);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
846
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
847 cl = ngx_alloc_chain_link(c->pool);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
848 if (cl == NULL) {
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
849 return NULL;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
850 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
851
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
852 cl->buf = b;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
853 cl->next = NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
854
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
855 *ll = cl;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
856 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
857
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
858 return out;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
859 }
8292
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
860
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
861
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
862 ngx_chain_t *
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
863 ngx_http_v3_create_trailers(ngx_http_request_t *r)
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
864 {
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
865 ngx_buf_t *b;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
866 ngx_chain_t *cl;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
867
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
868 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
869 "http3 create trailers");
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
870
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
871 /* XXX */
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
872
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
873 b = ngx_calloc_buf(r->pool);
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
874 if (b == NULL) {
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
875 return NULL;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
876 }
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
877
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
878 b->last_buf = 1;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
879
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
880 cl = ngx_alloc_chain_link(r->pool);
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
881 if (cl == NULL) {
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
882 return NULL;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
883 }
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
884
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
885 cl->buf = b;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
886 cl->next = NULL;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
887
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
888 return cl;
46e3542d51b3 Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents: 8291
diff changeset
889 }
8497
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
890
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
891
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
892 static ngx_int_t
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
893 ngx_http_v3_push_resources(ngx_http_request_t *r, ngx_chain_t ***out)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
894 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
895 u_char *start, *end, *last;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
896 ngx_str_t path;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
897 ngx_int_t rc;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
898 ngx_uint_t i, push;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
899 ngx_table_elt_t **h;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
900 ngx_http_v3_loc_conf_t *h3lcf;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
901 ngx_http_complex_value_t *pushes;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
902
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
903 h3lcf = ngx_http_get_module_loc_conf(r, ngx_http_v3_module);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
904
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
905 if (h3lcf->pushes) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
906 pushes = h3lcf->pushes->elts;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
907
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
908 for (i = 0; i < h3lcf->pushes->nelts; i++) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
909
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
910 if (ngx_http_complex_value(r, &pushes[i], &path) != NGX_OK) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
911 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
912 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
913
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
914 if (path.len == 0) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
915 continue;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
916 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
917
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
918 if (path.len == 3 && ngx_strncmp(path.data, "off", 3) == 0) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
919 continue;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
920 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
921
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
922 rc = ngx_http_v3_push_resource(r, &path, out);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
923
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
924 if (rc == NGX_ERROR) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
925 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
926 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
927
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
928 if (rc == NGX_ABORT) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
929 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
930 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
931
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
932 /* NGX_OK, NGX_DECLINED */
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
933 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
934 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
935
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
936 if (!h3lcf->push_preload) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
937 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
938 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
939
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
940 h = r->headers_out.link.elts;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
941
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
942 for (i = 0; i < r->headers_out.link.nelts; i++) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
943
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
944 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
945 "http3 parse link: \"%V\"", &h[i]->value);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
946
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
947 start = h[i]->value.data;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
948 end = h[i]->value.data + h[i]->value.len;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
949
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
950 next_link:
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
951
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
952 while (start < end && *start == ' ') { start++; }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
953
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
954 if (start == end || *start++ != '<') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
955 continue;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
956 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
957
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
958 while (start < end && *start == ' ') { start++; }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
959
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
960 for (last = start; last < end && *last != '>'; last++) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
961 /* void */
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
962 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
963
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
964 if (last == start || last == end) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
965 continue;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
966 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
967
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
968 path.len = last - start;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
969 path.data = start;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
970
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
971 start = last + 1;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
972
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
973 while (start < end && *start == ' ') { start++; }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
974
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
975 if (start == end) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
976 continue;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
977 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
978
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
979 if (*start == ',') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
980 start++;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
981 goto next_link;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
982 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
983
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
984 if (*start++ != ';') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
985 continue;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
986 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
987
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
988 last = ngx_strlchr(start, end, ',');
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
989
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
990 if (last == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
991 last = end;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
992 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
993
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
994 push = 0;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
995
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
996 for ( ;; ) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
997
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
998 while (start < last && *start == ' ') { start++; }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
999
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1000 if (last - start >= 6
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1001 && ngx_strncasecmp(start, (u_char *) "nopush", 6) == 0)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1002 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1003 start += 6;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1004
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1005 if (start == last || *start == ' ' || *start == ';') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1006 push = 0;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1007 break;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1008 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1009
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1010 goto next_param;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1011 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1012
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1013 if (last - start >= 11
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1014 && ngx_strncasecmp(start, (u_char *) "rel=preload", 11) == 0)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1015 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1016 start += 11;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1017
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1018 if (start == last || *start == ' ' || *start == ';') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1019 push = 1;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1020 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1021
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1022 goto next_param;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1023 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1024
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1025 if (last - start >= 4
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1026 && ngx_strncasecmp(start, (u_char *) "rel=", 4) == 0)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1027 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1028 start += 4;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1029
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1030 while (start < last && *start == ' ') { start++; }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1031
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1032 if (start == last || *start++ != '"') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1033 goto next_param;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1034 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1035
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1036 for ( ;; ) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1037
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1038 while (start < last && *start == ' ') { start++; }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1039
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1040 if (last - start >= 7
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1041 && ngx_strncasecmp(start, (u_char *) "preload", 7) == 0)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1042 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1043 start += 7;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1044
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1045 if (start < last && (*start == ' ' || *start == '"')) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1046 push = 1;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1047 break;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1048 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1049 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1050
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1051 while (start < last && *start != ' ' && *start != '"') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1052 start++;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1053 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1054
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1055 if (start == last) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1056 break;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1057 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1058
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1059 if (*start == '"') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1060 break;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1061 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1062
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1063 start++;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1064 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1065 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1066
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1067 next_param:
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1068
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1069 start = ngx_strlchr(start, last, ';');
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1070
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1071 if (start == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1072 break;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1073 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1074
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1075 start++;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1076 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1077
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1078 if (push) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1079 while (path.len && path.data[path.len - 1] == ' ') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1080 path.len--;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1081 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1082 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1083
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1084 if (push && path.len
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1085 && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/'))
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1086 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1087 rc = ngx_http_v3_push_resource(r, &path, out);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1088
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1089 if (rc == NGX_ERROR) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1090 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1091 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1092
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1093 if (rc == NGX_ABORT) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1094 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1095 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1096
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1097 /* NGX_OK, NGX_DECLINED */
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1098 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1099
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1100 if (last < end) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1101 start = last + 1;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1102 goto next_link;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1103 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1104 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1105
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1106 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1107 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1108
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1109
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1110 static ngx_int_t
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1111 ngx_http_v3_push_resource(ngx_http_request_t *r, ngx_str_t *path,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1112 ngx_chain_t ***ll)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1113 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1114 uint64_t push_id;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1115 ngx_int_t rc;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1116 ngx_chain_t *cl;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1117 ngx_connection_t *c;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1118 ngx_http_v3_srv_conf_t *h3scf;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1119 ngx_http_v3_connection_t *h3c;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1120
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1121 c = r->connection;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1122 h3c = c->qs->parent->data;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1123 h3scf = ngx_http_get_module_srv_conf(r, ngx_http_v3_module);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1124
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1125 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1126 "http3 push \"%V\" pushing:%ui/%ui id:%uL/%uL",
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1127 path, h3c->npushing, h3scf->max_concurrent_pushes,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1128 h3c->next_push_id, h3c->max_push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1129
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1130 if (!ngx_path_separator(path->data[0])) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1131 ngx_log_error(NGX_LOG_WARN, c->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1132 "non-absolute path \"%V\" not pushed", path);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1133 return NGX_DECLINED;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1134 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1135
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1136 if (h3c->next_push_id > h3c->max_push_id) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1137 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1138 "http3 abort pushes due to max_push_id");
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1139 return NGX_ABORT;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1140 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1141
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1142 if (h3c->npushing >= h3scf->max_concurrent_pushes) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1143 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1144 "http3 abort pushes due to max_concurrent_pushes");
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1145 return NGX_ABORT;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1146 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1147
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1148 push_id = h3c->next_push_id++;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1149
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1150 rc = ngx_http_v3_create_push_request(r, path, push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1151 if (rc != NGX_OK) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1152 return rc;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1153 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1154
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1155 cl = ngx_http_v3_create_push_promise(r, path, push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1156 if (cl == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1157 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1158 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1159
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1160 for (**ll = cl; **ll; *ll = &(**ll)->next);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1161
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1162 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1163 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1164
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1165
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1166 static ngx_int_t
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1167 ngx_http_v3_create_push_request(ngx_http_request_t *pr, ngx_str_t *path,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1168 uint64_t push_id)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1169 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1170 ngx_pool_t *pool;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1171 ngx_connection_t *c, *pc;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1172 ngx_http_request_t *r;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1173 ngx_http_log_ctx_t *ctx;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1174 ngx_http_connection_t *hc;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1175 ngx_http_core_srv_conf_t *cscf;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1176 ngx_http_v3_connection_t *h3c;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1177
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1178 pc = pr->connection;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1179
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1180 r = NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1181
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1182 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1183 "http3 create push request id:%uL", push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1184
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1185 c = ngx_http_v3_create_push_stream(pc, push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1186 if (c == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1187 return NGX_ABORT;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1188 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1189
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1190 hc = ngx_palloc(c->pool, sizeof(ngx_http_connection_t));
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1191 if (hc == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1192 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1193 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1194
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1195 h3c = c->qs->parent->data;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1196 ngx_memcpy(hc, h3c, sizeof(ngx_http_connection_t));
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1197 c->data = hc;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1198
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1199 ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1200 if (ctx == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1201 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1202 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1203
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1204 ctx->connection = c;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1205 ctx->request = NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1206 ctx->current_request = NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1207
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1208 c->log->handler = ngx_http_log_error;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1209 c->log->data = ctx;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1210 c->log->action = "processing pushed request headers";
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1211
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1212 c->log_error = NGX_ERROR_INFO;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1213
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1214 r = ngx_http_create_request(c);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1215 if (r == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1216 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1217 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1218
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1219 c->data = r;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1220
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1221 ngx_str_set(&r->http_protocol, "HTTP/3.0");
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1222
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1223 r->method_name = ngx_http_core_get_method;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1224 r->method = NGX_HTTP_GET;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1225
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1226 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1227
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1228 r->header_in = ngx_create_temp_buf(r->pool,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1229 cscf->client_header_buffer_size);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1230 if (r->header_in == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1231 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1232 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1233
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1234 if (ngx_list_init(&r->headers_in.headers, r->pool, 4,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1235 sizeof(ngx_table_elt_t))
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1236 != NGX_OK)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1237 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1238 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1239 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1240
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1241 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1242
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1243 r->schema.data = ngx_pstrdup(r->pool, &pr->schema);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1244 if (r->schema.data == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1245 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1246 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1247
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1248 r->schema.len = pr->schema.len;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1249
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1250 r->uri_start = ngx_pstrdup(r->pool, path);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1251 if (r->uri_start == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1252 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1253 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1254
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1255 r->uri_end = r->uri_start + path->len;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1256
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1257 if (ngx_http_parse_uri(r) != NGX_OK) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1258 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1259 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1260
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1261 if (ngx_http_process_request_uri(r) != NGX_OK) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1262 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1263 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1264
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1265 if (ngx_http_v3_set_push_header(r, "host", &pr->headers_in.server)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1266 != NGX_OK)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1267 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1268 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1269 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1270
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1271 if (pr->headers_in.accept_encoding) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1272 if (ngx_http_v3_set_push_header(r, "accept-encoding",
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1273 &pr->headers_in.accept_encoding->value)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1274 != NGX_OK)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1275 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1276 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1277 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1278 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1279
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1280 if (pr->headers_in.accept_language) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1281 if (ngx_http_v3_set_push_header(r, "accept-language",
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1282 &pr->headers_in.accept_language->value)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1283 != NGX_OK)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1284 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1285 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1286 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1287 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1288
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1289 if (pr->headers_in.user_agent) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1290 if (ngx_http_v3_set_push_header(r, "user-agent",
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1291 &pr->headers_in.user_agent->value)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1292 != NGX_OK)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1293 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1294 goto failed;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1295 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1296 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1297
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1298 c->read->handler = ngx_http_v3_push_request_handler;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1299 c->read->handler = ngx_http_v3_push_request_handler;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1300
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1301 ngx_post_event(c->read, &ngx_posted_events);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1302
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1303 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1304
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1305 failed:
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1306
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1307 if (r) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1308 ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1309 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1310
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1311 c->destroyed = 1;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1312
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1313 pool = c->pool;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1314
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1315 ngx_close_connection(c);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1316
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1317 ngx_destroy_pool(pool);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1318
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1319 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1320 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1321
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1322
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1323 static ngx_int_t
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1324 ngx_http_v3_set_push_header(ngx_http_request_t *r, const char *name,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1325 ngx_str_t *value)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1326 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1327 u_char *p;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1328 ngx_table_elt_t *h;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1329 ngx_http_header_t *hh;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1330 ngx_http_core_main_conf_t *cmcf;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1331
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1332 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1333 "http3 push header \"%s\": \"%V\"", name, value);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1334
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1335 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1336
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1337 p = ngx_pnalloc(r->pool, value->len + 1);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1338 if (p == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1339 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1340 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1341
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1342 ngx_memcpy(p, value->data, value->len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1343 p[value->len] = '\0';
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1344
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1345 h = ngx_list_push(&r->headers_in.headers);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1346 if (h == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1347 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1348 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1349
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1350 h->key.data = (u_char *) name;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1351 h->key.len = ngx_strlen(name);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1352 h->hash = ngx_hash_key(h->key.data, h->key.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1353 h->lowcase_key = (u_char *) name;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1354 h->value.data = p;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1355 h->value.len = value->len;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1356
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1357 hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1358 h->lowcase_key, h->key.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1359
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1360 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1361 return NGX_ERROR;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1362 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1363
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1364 return NGX_OK;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1365 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1366
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1367
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1368 static void
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1369 ngx_http_v3_push_request_handler(ngx_event_t *ev)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1370 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1371 ngx_connection_t *c;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1372 ngx_http_request_t *r;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1373
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1374 c = ev->data;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1375 r = c->data;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1376
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1377 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 push request handler");
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1378
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1379 ngx_http_process_request(r);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1380 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1381
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1382
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1383 static ngx_chain_t *
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1384 ngx_http_v3_create_push_promise(ngx_http_request_t *r, ngx_str_t *path,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1385 uint64_t push_id)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1386 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1387 size_t n, len;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1388 ngx_buf_t *b;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1389 ngx_chain_t *hl, *cl;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1390
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1391 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1392 "http3 create push promise id:%uL", push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1393
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1394 len = ngx_http_v3_encode_varlen_int(NULL, push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1395
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1396 len += ngx_http_v3_encode_header_block_prefix(NULL, 0, 0, 0);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1397
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1398 len += ngx_http_v3_encode_header_ri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1399 NGX_HTTP_V3_HEADER_METHOD_GET);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1400
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1401 len += ngx_http_v3_encode_header_lri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1402 NGX_HTTP_V3_HEADER_AUTHORITY,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1403 NULL, r->headers_in.server.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1404
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1405 if (path->len == 1 && path->data[0] == '/') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1406 len += ngx_http_v3_encode_header_ri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1407 NGX_HTTP_V3_HEADER_PATH_ROOT);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1408
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1409 } else {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1410 len += ngx_http_v3_encode_header_lri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1411 NGX_HTTP_V3_HEADER_PATH_ROOT,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1412 NULL, path->len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1413 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1414
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1415 if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1416 len += ngx_http_v3_encode_header_ri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1417 NGX_HTTP_V3_HEADER_SCHEME_HTTPS);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1418
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1419 } else if (r->schema.len == 4
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1420 && ngx_strncmp(r->schema.data, "http", 4) == 0)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1421 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1422 len += ngx_http_v3_encode_header_ri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1423 NGX_HTTP_V3_HEADER_SCHEME_HTTP);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1424
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1425 } else {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1426 len += ngx_http_v3_encode_header_lri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1427 NGX_HTTP_V3_HEADER_SCHEME_HTTP,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1428 NULL, r->schema.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1429 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1430
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1431 if (r->headers_in.accept_encoding) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1432 len += ngx_http_v3_encode_header_lri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1433 NGX_HTTP_V3_HEADER_ACCEPT_ENCODING, NULL,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1434 r->headers_in.accept_encoding->value.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1435 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1436
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1437 if (r->headers_in.accept_language) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1438 len += ngx_http_v3_encode_header_lri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1439 NGX_HTTP_V3_HEADER_ACCEPT_LANGUAGE, NULL,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1440 r->headers_in.accept_language->value.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1441 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1442
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1443 if (r->headers_in.user_agent) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1444 len += ngx_http_v3_encode_header_lri(NULL, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1445 NGX_HTTP_V3_HEADER_USER_AGENT, NULL,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1446 r->headers_in.user_agent->value.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1447 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1448
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1449 b = ngx_create_temp_buf(r->pool, len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1450 if (b == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1451 return NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1452 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1453
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1454 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, push_id);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1455
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1456 b->last = (u_char *) ngx_http_v3_encode_header_block_prefix(b->last,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1457 0, 0, 0);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1458
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1459 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1460 NGX_HTTP_V3_HEADER_METHOD_GET);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1461
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1462 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1463 NGX_HTTP_V3_HEADER_AUTHORITY,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1464 r->headers_in.server.data,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1465 r->headers_in.server.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1466
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1467 if (path->len == 1 && path->data[0] == '/') {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1468 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1469 NGX_HTTP_V3_HEADER_PATH_ROOT);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1470
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1471 } else {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1472 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1473 NGX_HTTP_V3_HEADER_PATH_ROOT,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1474 path->data, path->len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1475 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1476
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1477 if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1478 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1479 NGX_HTTP_V3_HEADER_SCHEME_HTTPS);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1480
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1481 } else if (r->schema.len == 4
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1482 && ngx_strncmp(r->schema.data, "http", 4) == 0)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1483 {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1484 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1485 NGX_HTTP_V3_HEADER_SCHEME_HTTP);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1486
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1487 } else {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1488 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1489 NGX_HTTP_V3_HEADER_SCHEME_HTTP,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1490 r->schema.data, r->schema.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1491 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1492
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1493 if (r->headers_in.accept_encoding) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1494 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1495 NGX_HTTP_V3_HEADER_ACCEPT_ENCODING,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1496 r->headers_in.accept_encoding->value.data,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1497 r->headers_in.accept_encoding->value.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1498 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1499
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1500 if (r->headers_in.accept_language) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1501 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1502 NGX_HTTP_V3_HEADER_ACCEPT_LANGUAGE,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1503 r->headers_in.accept_language->value.data,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1504 r->headers_in.accept_language->value.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1505 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1506
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1507 if (r->headers_in.user_agent) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1508 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1509 NGX_HTTP_V3_HEADER_USER_AGENT,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1510 r->headers_in.user_agent->value.data,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1511 r->headers_in.user_agent->value.len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1512 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1513
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1514 cl = ngx_alloc_chain_link(r->pool);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1515 if (cl == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1516 return NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1517 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1518
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1519 cl->buf = b;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1520 cl->next = NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1521
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1522 n = b->last - b->pos;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1523
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1524 len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_PUSH_PROMISE)
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1525 + ngx_http_v3_encode_varlen_int(NULL, n);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1526
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1527 b = ngx_create_temp_buf(r->pool, len);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1528 if (b == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1529 return NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1530 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1531
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1532 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last,
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1533 NGX_HTTP_V3_FRAME_PUSH_PROMISE);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1534 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, n);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1535
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1536 hl = ngx_alloc_chain_link(r->pool);
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1537 if (hl == NULL) {
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1538 return NULL;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1539 }
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1540
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1541 hl->buf = b;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1542 hl->next = cl;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1543
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1544 return hl;
0596fe1aee16 HTTP/3: server pushes.
Roman Arutyunyan <arut@nginx.com>
parents: 8494
diff changeset
1545 }