annotate src/http/v2/ngx_http_v2_filter_module.c @ 6593:b3b7e33083ac

Introduced ngx_inet_get_port() and ngx_inet_set_port() functions.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 20 Jun 2016 11:50:39 +0300
parents 155871d773cc
children 6f69e3c0f780
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
2 /*
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
3 * Copyright (C) Nginx, Inc.
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
4 * Copyright (C) Valentin V. Bartenev
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
5 */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
6
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
7
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
10 #include <ngx_http.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
11 #include <nginx.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
12 #include <ngx_http_v2_module.h>
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
13
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
14
6279
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
15 /*
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
16 * This returns precise number of octets for values in range 0..253
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
17 * and estimate number for the rest, but not smaller than required.
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
18 */
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
19
c72eaf694d99 HTTP/2: improved the ngx_http_v2_integer_octets(v) macro.
Valentin Bartenev <vbart@nginx.com>
parents: 6277
diff changeset
20 #define ngx_http_v2_integer_octets(v) (1 + (v) / 127)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
21
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
22 #define ngx_http_v2_literal_size(h) \
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
23 (ngx_http_v2_integer_octets(sizeof(h) - 1) + sizeof(h) - 1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
24
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
25 #define ngx_http_v2_indexed(i) (128 + (i))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
26 #define ngx_http_v2_inc_indexed(i) (64 + (i))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
27
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
28 #define ngx_http_v2_write_name(dst, src, len, tmp) \
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
29 ngx_http_v2_string_encode(dst, src, len, tmp, 1)
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
30 #define ngx_http_v2_write_value(dst, src, len, tmp) \
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
31 ngx_http_v2_string_encode(dst, src, len, tmp, 0)
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
32
6276
0efc16d55adb HTTP/2: introduced NGX_HTTP_V2_ENCODE_* macros.
Valentin Bartenev <vbart@nginx.com>
parents: 6275
diff changeset
33 #define NGX_HTTP_V2_ENCODE_RAW 0
0efc16d55adb HTTP/2: introduced NGX_HTTP_V2_ENCODE_* macros.
Valentin Bartenev <vbart@nginx.com>
parents: 6275
diff changeset
34 #define NGX_HTTP_V2_ENCODE_HUFF 0x80
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
35
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
36 #define NGX_HTTP_V2_STATUS_INDEX 8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
37 #define NGX_HTTP_V2_STATUS_200_INDEX 8
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
38 #define NGX_HTTP_V2_STATUS_204_INDEX 9
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
39 #define NGX_HTTP_V2_STATUS_206_INDEX 10
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
40 #define NGX_HTTP_V2_STATUS_304_INDEX 11
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
41 #define NGX_HTTP_V2_STATUS_400_INDEX 12
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
42 #define NGX_HTTP_V2_STATUS_404_INDEX 13
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
43 #define NGX_HTTP_V2_STATUS_500_INDEX 14
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
44
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
45 #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX 28
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
46 #define NGX_HTTP_V2_CONTENT_TYPE_INDEX 31
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
47 #define NGX_HTTP_V2_DATE_INDEX 33
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
48 #define NGX_HTTP_V2_LAST_MODIFIED_INDEX 44
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
49 #define NGX_HTTP_V2_LOCATION_INDEX 46
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
50 #define NGX_HTTP_V2_SERVER_INDEX 54
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
51 #define NGX_HTTP_V2_VARY_INDEX 59
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
52
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
53
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
54 static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
55 u_char *tmp, ngx_uint_t lower);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
56 static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
57 ngx_uint_t value);
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
58 static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
59 ngx_http_request_t *r, u_char *pos, u_char *end);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
60
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
61 static ngx_chain_t *ngx_http_v2_send_chain(ngx_connection_t *fc,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
62 ngx_chain_t *in, off_t limit);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
63
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
64 static ngx_chain_t *ngx_http_v2_filter_get_shadow(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
65 ngx_http_v2_stream_t *stream, ngx_buf_t *buf, off_t offset, off_t size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
66 static ngx_http_v2_out_frame_t *ngx_http_v2_filter_get_data_frame(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
67 ngx_http_v2_stream_t *stream, size_t len, ngx_chain_t *first,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
68 ngx_chain_t *last);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
69
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
70 static ngx_inline ngx_int_t ngx_http_v2_flow_control(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
71 ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
72 static void ngx_http_v2_waiting_queue(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
73 ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
74
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
75 static ngx_inline ngx_int_t ngx_http_v2_filter_send(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
76 ngx_connection_t *fc, ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
77
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
78 static ngx_int_t ngx_http_v2_headers_frame_handler(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
79 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
80 static ngx_int_t ngx_http_v2_data_frame_handler(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
81 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
82 static ngx_inline void ngx_http_v2_handle_frame(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
83 ngx_http_v2_stream_t *stream, ngx_http_v2_out_frame_t *frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
84 static ngx_inline void ngx_http_v2_handle_stream(
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
85 ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
86
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
87 static void ngx_http_v2_filter_cleanup(void *data);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
88
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
89 static ngx_int_t ngx_http_v2_filter_init(ngx_conf_t *cf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
90
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
91
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
92 static ngx_http_module_t ngx_http_v2_filter_module_ctx = {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
93 NULL, /* preconfiguration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
94 ngx_http_v2_filter_init, /* postconfiguration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
95
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
96 NULL, /* create main configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
97 NULL, /* init main configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
98
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
99 NULL, /* create server configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
100 NULL, /* merge server configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
101
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
102 NULL, /* create location configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
103 NULL /* merge location configuration */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
104 };
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
105
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
106
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
107 ngx_module_t ngx_http_v2_filter_module = {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
108 NGX_MODULE_V1,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
109 &ngx_http_v2_filter_module_ctx, /* module context */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
110 NULL, /* module directives */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
111 NGX_HTTP_MODULE, /* module type */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
112 NULL, /* init master */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
113 NULL, /* init module */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
114 NULL, /* init process */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
115 NULL, /* init thread */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
116 NULL, /* exit thread */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
117 NULL, /* exit process */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
118 NULL, /* exit master */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
119 NGX_MODULE_V1_PADDING
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
120 };
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
121
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
122
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
123 static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
124
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
125
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
126 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
127 ngx_http_v2_header_filter(ngx_http_request_t *r)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
128 {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
129 u_char status, *pos, *start, *p, *tmp;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
130 size_t len, tmp_len;
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
131 ngx_str_t host, location;
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
132 ngx_uint_t i, port;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
133 ngx_list_part_t *part;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
134 ngx_table_elt_t *header;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
135 ngx_connection_t *fc;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
136 ngx_http_cleanup_t *cln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
137 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
138 ngx_http_core_loc_conf_t *clcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
139 ngx_http_core_srv_conf_t *cscf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
140 u_char addr[NGX_SOCKADDR_STRLEN];
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
141
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
142 static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7";
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
143 #if (NGX_HTTP_GZIP)
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
144 static const u_char accept_encoding[12] =
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
145 "\x8b\x84\x84\x2d\x69\x5b\x05\x44\x3c\x86\xaa\x6f";
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
146 #endif
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
147
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
148 static size_t nginx_ver_len = ngx_http_v2_literal_size(NGINX_VER);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
149 static u_char nginx_ver[ngx_http_v2_literal_size(NGINX_VER)];
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
150
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
151 if (!r->stream) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
152 return ngx_http_next_header_filter(r);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
153 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
154
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
155 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
156 "http2 header filter");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
157
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
158 if (r->header_sent) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
159 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
160 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
161
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
162 r->header_sent = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
163
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
164 if (r != r->main) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
165 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
166 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
167
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
168 if (r->method == NGX_HTTP_HEAD) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
169 r->header_only = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
170 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
171
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
172 switch (r->headers_out.status) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
173
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
174 case NGX_HTTP_OK:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
175 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_200_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
176 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
177
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
178 case NGX_HTTP_NO_CONTENT:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
179 r->header_only = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
180
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
181 ngx_str_null(&r->headers_out.content_type);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
182
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
183 r->headers_out.content_length = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
184 r->headers_out.content_length_n = -1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
185
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
186 r->headers_out.last_modified_time = -1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
187 r->headers_out.last_modified = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
188
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
189 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_204_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
190 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
191
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
192 case NGX_HTTP_PARTIAL_CONTENT:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
193 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_206_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
194 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
195
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
196 case NGX_HTTP_NOT_MODIFIED:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
197 r->header_only = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
198 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_304_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
199 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
200
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
201 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
202 r->headers_out.last_modified_time = -1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
203 r->headers_out.last_modified = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
204
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
205 switch (r->headers_out.status) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
206
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
207 case NGX_HTTP_BAD_REQUEST:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
208 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_400_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
209 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
210
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
211 case NGX_HTTP_NOT_FOUND:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
212 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_404_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
213 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
214
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
215 case NGX_HTTP_INTERNAL_SERVER_ERROR:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
216 status = ngx_http_v2_indexed(NGX_HTTP_V2_STATUS_500_INDEX);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
217 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
218
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
219 default:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
220 status = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
221 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
222 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
223
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
224 len = status ? 1 : 1 + ngx_http_v2_literal_size("418");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
225
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
226 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
227
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
228 if (r->headers_out.server == NULL) {
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
229 len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx));
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
230 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
231
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
232 if (r->headers_out.date == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
233 len += 1 + ngx_http_v2_literal_size("Wed, 31 Dec 1986 18:00:00 GMT");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
234 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
235
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
236 if (r->headers_out.content_type.len) {
6274
b2de4a56b860 HTTP/2: fixed header block size calculation.
Valentin Bartenev <vbart@nginx.com>
parents: 6251
diff changeset
237 len += 1 + NGX_HTTP_V2_INT_OCTETS + r->headers_out.content_type.len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
238
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
239 if (r->headers_out.content_type_len == r->headers_out.content_type.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
240 && r->headers_out.charset.len)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
241 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
242 len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
243 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
244 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
245
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
246 if (r->headers_out.content_length == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
247 && r->headers_out.content_length_n >= 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
248 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
249 len += 1 + ngx_http_v2_integer_octets(NGX_OFF_T_LEN) + NGX_OFF_T_LEN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
250 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
251
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
252 if (r->headers_out.last_modified == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
253 && r->headers_out.last_modified_time != -1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
254 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
255 len += 1 + ngx_http_v2_literal_size("Wed, 31 Dec 1986 18:00:00 GMT");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
256 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
257
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
258 fc = r->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
259
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
260 if (r->headers_out.location && r->headers_out.location->value.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
261
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
262 if (r->headers_out.location->value.data[0] == '/') {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
263 if (clcf->server_name_in_redirect) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
264 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
265 host = cscf->server_name;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
266
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
267 } else if (r->headers_in.server.len) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
268 host = r->headers_in.server;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
269
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
270 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
271 host.len = NGX_SOCKADDR_STRLEN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
272 host.data = addr;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
273
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
274 if (ngx_connection_local_sockaddr(fc, &host, 0) != NGX_OK) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
275 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
276 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
277 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
278
6593
b3b7e33083ac Introduced ngx_inet_get_port() and ngx_inet_set_port() functions.
Roman Arutyunyan <arut@nginx.com>
parents: 6451
diff changeset
279 port = ngx_inet_get_port(fc->local_sockaddr);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
280
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
281 location.len = sizeof("https://") - 1 + host.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
282 + r->headers_out.location->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
283
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
284 if (clcf->port_in_redirect) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
285
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
286 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
287 if (fc->ssl)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
288 port = (port == 443) ? 0 : port;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
289 else
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
290 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
291 port = (port == 80) ? 0 : port;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
292
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
293 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
294 port = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
295 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
296
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
297 if (port) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
298 location.len += sizeof(":65535") - 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
299 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
300
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
301 location.data = ngx_pnalloc(r->pool, location.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
302 if (location.data == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
303 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
304 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
305
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
306 p = ngx_cpymem(location.data, "http", sizeof("http") - 1);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
307
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
308 #if (NGX_HTTP_SSL)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
309 if (fc->ssl) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
310 *p++ = 's';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
311 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
312 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
313
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
314 *p++ = ':'; *p++ = '/'; *p++ = '/';
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
315 p = ngx_cpymem(p, host.data, host.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
316
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
317 if (port) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
318 p = ngx_sprintf(p, ":%ui", port);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
319 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
320
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
321 p = ngx_cpymem(p, r->headers_out.location->value.data,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
322 r->headers_out.location->value.len);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
323
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
324 /* update r->headers_out.location->value for possible logging */
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
325
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
326 r->headers_out.location->value.len = p - location.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
327 r->headers_out.location->value.data = location.data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
328 ngx_str_set(&r->headers_out.location->key, "Location");
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
329 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
330
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
331 r->headers_out.location->hash = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
332
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
333 len += 1 + NGX_HTTP_V2_INT_OCTETS + r->headers_out.location->value.len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
334 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
335
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
336 tmp_len = len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
337
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
338 #if (NGX_HTTP_GZIP)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
339 if (r->gzip_vary) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
340 if (clcf->gzip_vary) {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
341 len += 1 + sizeof(accept_encoding);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
342
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
343 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
344 r->gzip_vary = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
345 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
346 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
347 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
348
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
349 part = &r->headers_out.headers.part;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
350 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
351
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
352 for (i = 0; /* void */; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
353
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
354 if (i >= part->nelts) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
355 if (part->next == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
356 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
357 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
358
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
359 part = part->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
360 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
361 i = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
362 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
363
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
364 if (header[i].hash == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
365 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
366 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
367
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
368 if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) {
6400
b4c28876d2c3 HTTP/2: use local pointer instead of r->connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6395
diff changeset
369 ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
370 "too long response header name: \"%V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
371 &header[i].key);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
372 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
373 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
374
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
375 if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) {
6400
b4c28876d2c3 HTTP/2: use local pointer instead of r->connection.
Valentin Bartenev <vbart@nginx.com>
parents: 6395
diff changeset
376 ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
377 "too long response header value: \"%V: %V\"",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
378 &header[i].key, &header[i].value);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
379 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
380 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
381
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
382 len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
383 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len;
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
384
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
385 if (header[i].key.len > tmp_len) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
386 tmp_len = header[i].key.len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
387 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
388
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
389 if (header[i].value.len > tmp_len) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
390 tmp_len = header[i].value.len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
391 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
392 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
393
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
394 tmp = ngx_palloc(r->pool, tmp_len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
395 pos = ngx_pnalloc(r->pool, len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
396
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
397 if (pos == NULL || tmp == NULL) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
398 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
399 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
400
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
401 start = pos;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
402
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
403 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
404 "http2 output header: \":status: %03ui\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
405 r->headers_out.status);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
406
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
407 if (status) {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
408 *pos++ = status;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
409
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
410 } else {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
411 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_STATUS_INDEX);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
412 *pos++ = NGX_HTTP_V2_ENCODE_RAW | 3;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
413 pos = ngx_sprintf(pos, "%03ui", r->headers_out.status);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
414 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
415
6449
e5076b96fd01 Reconsidered server_tokens with an empty value.
Ruslan Ermilov <ru@nginx.com>
parents: 6434
diff changeset
416 if (r->headers_out.server == NULL) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
417 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
418 "http2 output header: \"server: %s\"",
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
419 clcf->server_tokens ? NGINX_VER : "nginx");
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
420
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
421 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
422
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
423 if (clcf->server_tokens) {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
424 if (nginx_ver[0] == '\0') {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
425 p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
426 sizeof(NGINX_VER) - 1, tmp);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
427 nginx_ver_len = p - nginx_ver;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
428 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
429
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
430 pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len);
6451
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
431
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
432 } else {
155871d773cc Backed out server_tokens changes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6449
diff changeset
433 pos = ngx_cpymem(pos, nginx, sizeof(nginx));
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
434 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
435 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
436
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
437 if (r->headers_out.date == NULL) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
438 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
439 "http2 output header: \"date: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
440 &ngx_cached_http_time);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
441
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
442 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_DATE_INDEX);
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
443 pos = ngx_http_v2_write_value(pos, ngx_cached_http_time.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
444 ngx_cached_http_time.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
445 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
446
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
447 if (r->headers_out.content_type.len) {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
448 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_CONTENT_TYPE_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
449
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
450 if (r->headers_out.content_type_len == r->headers_out.content_type.len
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
451 && r->headers_out.charset.len)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
452 {
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
453 len = r->headers_out.content_type.len + sizeof("; charset=") - 1
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
454 + r->headers_out.charset.len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
455
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
456 p = ngx_pnalloc(r->pool, len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
457 if (p == NULL) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
458 return NGX_ERROR;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
459 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
460
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
461 p = ngx_cpymem(p, r->headers_out.content_type.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
462 r->headers_out.content_type.len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
463
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
464 p = ngx_cpymem(p, "; charset=", sizeof("; charset=") - 1);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
465
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
466 p = ngx_cpymem(p, r->headers_out.charset.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
467 r->headers_out.charset.len);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
468
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
469 /* updated r->headers_out.content_type is also needed for logging */
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
470
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
471 r->headers_out.content_type.len = len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
472 r->headers_out.content_type.data = p - len;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
473 }
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
474
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
475 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
476 "http2 output header: \"content-type: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
477 &r->headers_out.content_type);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
478
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
479 pos = ngx_http_v2_write_value(pos, r->headers_out.content_type.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
480 r->headers_out.content_type.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
481 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
482
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
483 if (r->headers_out.content_length == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
484 && r->headers_out.content_length_n >= 0)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
485 {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
486 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
487 "http2 output header: \"content-length: %O\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
488 r->headers_out.content_length_n);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
489
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
490 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_CONTENT_LENGTH_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
491
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
492 p = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
493 pos = ngx_sprintf(pos + 1, "%O", r->headers_out.content_length_n);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
494 *p = NGX_HTTP_V2_ENCODE_RAW | (u_char) (pos - p - 1);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
495 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
496
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
497 if (r->headers_out.last_modified == NULL
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
498 && r->headers_out.last_modified_time != -1)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
499 {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
500 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LAST_MODIFIED_INDEX);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
501
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
502 ngx_http_time(pos, r->headers_out.last_modified_time);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
503 len = sizeof("Wed, 31 Dec 1986 18:00:00 GMT") - 1;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
504
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
505 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
506 "http2 output header: \"last-modified: %*s\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
507 len, pos);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
508
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
509 /*
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
510 * Date will always be encoded using huffman in the temporary buffer,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
511 * so it's safe here to use src and dst pointing to the same address.
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
512 */
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
513 pos = ngx_http_v2_write_value(pos, pos, len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
514 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
515
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
516 if (r->headers_out.location && r->headers_out.location->value.len) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
517 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
518 "http2 output header: \"location: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
519 &r->headers_out.location->value);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
520
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
521 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LOCATION_INDEX);
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
522 pos = ngx_http_v2_write_value(pos, r->headers_out.location->value.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
523 r->headers_out.location->value.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
524 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
525
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
526 #if (NGX_HTTP_GZIP)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
527 if (r->gzip_vary) {
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
528 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
529 "http2 output header: \"vary: Accept-Encoding\"");
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
530
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
531 *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_VARY_INDEX);
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
532 pos = ngx_cpymem(pos, accept_encoding, sizeof(accept_encoding));
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
533 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
534 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
535
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
536 part = &r->headers_out.headers.part;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
537 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
538
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
539 for (i = 0; /* void */; i++) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
540
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
541 if (i >= part->nelts) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
542 if (part->next == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
543 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
544 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
545
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
546 part = part->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
547 header = part->elts;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
548 i = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
549 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
550
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
551 if (header[i].hash == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
552 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
553 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
554
6401
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
555 #if (NGX_DEBUG)
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
556 if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) {
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
557 ngx_strlow(tmp, header[i].key.data, header[i].key.len);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
558
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
559 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0,
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
560 "http2 output header: \"%*s: %V\"",
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
561 header[i].key.len, tmp, &header[i].value);
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
562 }
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
563 #endif
6812ca9a8002 HTTP/2: added debug logging of response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6400
diff changeset
564
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
565 *pos++ = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
566
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
567 pos = ngx_http_v2_write_name(pos, header[i].key.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
568 header[i].key.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
569
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
570 pos = ngx_http_v2_write_value(pos, header[i].value.data,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
571 header[i].value.len, tmp);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
572 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
573
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
574 frame = ngx_http_v2_create_headers_frame(r, start, pos);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
575 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
576 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
577 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
578
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
579 ngx_http_v2_queue_blocked_frame(r->stream->connection, frame);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
580
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
581 cln = ngx_http_cleanup_add(r, 0);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
582 if (cln == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
583 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
584 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
585
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
586 cln->handler = ngx_http_v2_filter_cleanup;
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
587 cln->data = r->stream;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
588
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
589 r->stream->queued = 1;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
590
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
591 fc->send_chain = ngx_http_v2_send_chain;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
592 fc->need_last_buf = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
593
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
594 return ngx_http_v2_filter_send(fc, r->stream);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
595 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
596
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
597
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
598 static u_char *
6395
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
599 ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp,
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
600 ngx_uint_t lower)
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
601 {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
602 size_t hlen;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
603
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
604 hlen = ngx_http_v2_huff_encode(src, len, tmp, lower);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
605
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
606 if (hlen > 0) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
607 *dst = NGX_HTTP_V2_ENCODE_HUFF;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
608 dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), hlen);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
609 return ngx_cpymem(dst, tmp, hlen);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
610 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
611
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
612 *dst = NGX_HTTP_V2_ENCODE_RAW;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
613 dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
614
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
615 if (lower) {
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
616 ngx_strlow(dst, src, len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
617 return dst + len;
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
618 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
619
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
620 return ngx_cpymem(dst, src, len);
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
621 }
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
622
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
623
ba3c2ca21aa5 HTTP/2: implemented HPACK Huffman encoding for response headers.
Valentin Bartenev <vbart@nginx.com>
parents: 6377
diff changeset
624 static u_char *
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
625 ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
626 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
627 if (value < prefix) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
628 *pos++ |= value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
629 return pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
630 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
631
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
632 *pos++ |= prefix;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
633 value -= prefix;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
634
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
635 while (value >= 128) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
636 *pos++ = value % 128 + 128;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
637 value /= 128;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
638 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
639
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
640 *pos++ = (u_char) value;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
641
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
642 return pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
643 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
644
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
645
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
646 static ngx_http_v2_out_frame_t *
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
647 ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
648 u_char *end)
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
649 {
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
650 u_char type, flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
651 size_t rest, frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
652 ngx_buf_t *b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
653 ngx_chain_t *cl, **ll;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
654 ngx_http_v2_stream_t *stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
655 ngx_http_v2_out_frame_t *frame;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
656
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
657 stream = r->stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
658 rest = end - pos;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
659
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
660 frame = ngx_palloc(r->pool, sizeof(ngx_http_v2_out_frame_t));
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
661 if (frame == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
662 return NULL;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
663 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
664
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
665 frame->handler = ngx_http_v2_headers_frame_handler;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
666 frame->stream = stream;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
667 frame->length = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
668 frame->blocked = 1;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
669 frame->fin = r->header_only;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
670
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
671 ll = &frame->first;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
672
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
673 type = NGX_HTTP_V2_HEADERS_FRAME;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
674 flags = r->header_only ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
675 frame_size = stream->connection->frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
676
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
677 for ( ;; ) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
678 if (rest <= frame_size) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
679 frame_size = rest;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
680 flags |= NGX_HTTP_V2_END_HEADERS_FLAG;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
681 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
682
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
683 b = ngx_create_temp_buf(r->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
684 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
685 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
686 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
687
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
688 b->last = ngx_http_v2_write_len_and_type(b->last, frame_size, type);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
689 *b->last++ = flags;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
690 b->last = ngx_http_v2_write_sid(b->last, stream->node->id);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
691
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
692 b->tag = (ngx_buf_tag_t) &ngx_http_v2_module;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
693
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
694 cl = ngx_alloc_chain_link(r->pool);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
695 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
696 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
697 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
698
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
699 cl->buf = b;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
700
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
701 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
702 ll = &cl->next;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
703
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
704 b = ngx_calloc_buf(r->pool);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
705 if (b == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
706 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
707 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
708
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
709 b->pos = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
710
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
711 pos += frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
712
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
713 b->last = pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
714 b->start = b->pos;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
715 b->end = b->last;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
716 b->temporary = 1;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
717
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
718 cl = ngx_alloc_chain_link(r->pool);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
719 if (cl == NULL) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
720 return NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
721 }
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
722
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
723 cl->buf = b;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
724
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
725 *ll = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
726 ll = &cl->next;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
727
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
728 rest -= frame_size;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
729
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
730 if (rest) {
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
731 type = NGX_HTTP_V2_CONTINUATION_FRAME;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
732 flags = NGX_HTTP_V2_NO_FLAG;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
733 continue;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
734 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
735
6277
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
736 b->last_buf = r->header_only;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
737 cl->next = NULL;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
738 frame->last = cl;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
739
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
740 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
741 "http2:%ui create HEADERS frame %p: len:%uz",
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
742 stream->node->id, frame, frame->length);
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
743
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
744 return frame;
b930e598a199 HTTP/2: fixed splitting of response headers on CONTINUATION frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6276
diff changeset
745 }
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
746 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
747
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
748
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
749 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
750 ngx_http_v2_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
751 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
752 off_t size, offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
753 size_t rest, frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
754 ngx_chain_t *cl, *out, **ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
755 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
756 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
757 ngx_http_v2_loc_conf_t *h2lcf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
758 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
759 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
760
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
761 r = fc->data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
762 stream = r->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
763
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
764 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
765 size = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
766 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
767
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
768 while (in) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
769 size = ngx_buf_size(in->buf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
770
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
771 if (size || in->buf->last_buf) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
772 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
773 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
774
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
775 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
776 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
777
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
778 if (in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
779
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
780 if (stream->queued) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
781 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
782 fc->write->ready = 0;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
783
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
784 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
785 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
786 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
787
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
788 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
789 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
790
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
791 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
792
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
793 if (size && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
794 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
795 fc->write->ready = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
796 return in;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
797 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
798
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
799 if (in->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
800 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
801 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
802 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
803 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
804
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
805 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
806 in->buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
807
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
808 offset = ngx_buf_in_memory(in->buf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
809 ? (cl->buf->pos - in->buf->pos)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
810 : (cl->buf->file_pos - in->buf->file_pos);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
811
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
812 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
813 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
814
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
815 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
816 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
817 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
818
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
819 if (limit == 0 || limit > (off_t) h2c->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
820 limit = h2c->send_window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
821 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
822
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
823 if (limit > stream->send_window) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
824 limit = (stream->send_window > 0) ? stream->send_window : 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
825 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
826
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
827 h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
828
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
829 frame_size = (h2lcf->chunk_size < h2c->frame_size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
830 ? h2lcf->chunk_size : h2c->frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
831
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
832 #if (NGX_SUPPRESS_WARN)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
833 cl = NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
834 #endif
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
835
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
836 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
837 if ((off_t) frame_size > limit) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
838 frame_size = (size_t) limit;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
839 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
840
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
841 ln = &out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
842 rest = frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
843
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
844 while ((off_t) rest >= size) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
845
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
846 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
847 cl = ngx_http_v2_filter_get_shadow(stream, in->buf,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
848 offset, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
849 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
850 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
851 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
852
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
853 offset = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
854
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
855 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
856 cl = ngx_alloc_chain_link(r->pool);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
857 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
858 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
859 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
860
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
861 cl->buf = in->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
862 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
863
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
864 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
865 ln = &cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
866
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
867 rest -= (size_t) size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
868 in = in->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
869
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
870 if (in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
871 frame_size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
872 rest = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
873 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
874 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
875
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
876 size = ngx_buf_size(in->buf);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
877 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
878
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
879 if (rest) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
880 cl = ngx_http_v2_filter_get_shadow(stream, in->buf, offset, rest);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
881 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
882 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
883 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
884
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
885 cl->buf->flush = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
886 cl->buf->last_buf = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
887
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
888 *ln = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
889
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
890 offset += rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
891 size -= rest;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
892 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
893
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
894 frame = ngx_http_v2_filter_get_data_frame(stream, frame_size, out, cl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
895 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
896 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
897 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
898
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
899 ngx_http_v2_queue_frame(h2c, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
900
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
901 h2c->send_window -= frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
902
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
903 stream->send_window -= frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
904 stream->queued++;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
905
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
906 if (in == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
907 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
908 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
909
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
910 limit -= frame_size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
911
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
912 if (limit == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
913 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
914 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
915 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
916
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
917 if (offset) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
918 cl = ngx_http_v2_filter_get_shadow(stream, in->buf, offset, size);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
919 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
920 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
921 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
922
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
923 in->buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
924 ngx_free_chain(r->pool, cl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
925 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
926
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
927 if (ngx_http_v2_filter_send(fc, stream) == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
928 return NGX_CHAIN_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
929 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
930
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
931 if (in && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) {
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
932 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
933 fc->write->ready = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
934 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
935
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
936 return in;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
937 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
938
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
939
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
940 static ngx_chain_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
941 ngx_http_v2_filter_get_shadow(ngx_http_v2_stream_t *stream, ngx_buf_t *buf,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
942 off_t offset, off_t size)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
943 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
944 ngx_buf_t *chunk;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
945 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
946
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
947 cl = ngx_chain_get_free_buf(stream->request->pool, &stream->free_bufs);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
948 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
949 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
950 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
951
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
952 chunk = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
953
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
954 ngx_memcpy(chunk, buf, sizeof(ngx_buf_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
955
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
956 chunk->tag = (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
957 chunk->shadow = buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
958
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
959 if (ngx_buf_in_memory(chunk)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
960 chunk->pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
961 chunk->last = chunk->pos + size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
962 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
963
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
964 if (chunk->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
965 chunk->file_pos += offset;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
966 chunk->file_last = chunk->file_pos + size;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
967 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
968
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
969 return cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
970 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
971
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
972
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
973 static ngx_http_v2_out_frame_t *
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
974 ngx_http_v2_filter_get_data_frame(ngx_http_v2_stream_t *stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
975 size_t len, ngx_chain_t *first, ngx_chain_t *last)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
976 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
977 u_char flags;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
978 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
979 ngx_chain_t *cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
980 ngx_http_v2_out_frame_t *frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
981
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
982
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
983 frame = stream->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
984
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
985 if (frame) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
986 stream->free_frames = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
987
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
988 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
989 frame = ngx_palloc(stream->request->pool,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
990 sizeof(ngx_http_v2_out_frame_t));
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
991 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
992 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
993 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
994 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
995
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
996 flags = last->buf->last_buf ? NGX_HTTP_V2_END_STREAM_FLAG : 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
997
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
998 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, stream->request->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
999 "http2:%ui create DATA frame %p: len:%uz flags:%ui",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1000 stream->node->id, frame, len, (ngx_uint_t) flags);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1001
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1002 cl = ngx_chain_get_free_buf(stream->request->pool,
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1003 &stream->free_frame_headers);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1004 if (cl == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1005 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1006 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1007
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1008 buf = cl->buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1009
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1010 if (!buf->start) {
6251
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1011 buf->start = ngx_palloc(stream->request->pool,
Maxim Dounin <mdounin@mdounin.ru>
parents: 6246
diff changeset
1012 NGX_HTTP_V2_FRAME_HEADER_SIZE);
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1013 if (buf->start == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1014 return NULL;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1015 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1016
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1017 buf->end = buf->start + NGX_HTTP_V2_FRAME_HEADER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1018 buf->last = buf->end;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1019
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1020 buf->tag = (ngx_buf_tag_t) &ngx_http_v2_module;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1021 buf->memory = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1022 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1023
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1024 buf->pos = buf->start;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1025 buf->last = buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1026
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1027 buf->last = ngx_http_v2_write_len_and_type(buf->last, len,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1028 NGX_HTTP_V2_DATA_FRAME);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1029 *buf->last++ = flags;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1030
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1031 buf->last = ngx_http_v2_write_sid(buf->last, stream->node->id);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1032
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1033 cl->next = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1034 first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1035
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1036 last->buf->flush = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1037
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1038 frame->first = first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1039 frame->last = last;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1040 frame->handler = ngx_http_v2_data_frame_handler;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1041 frame->stream = stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1042 frame->length = len;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1043 frame->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1044 frame->fin = last->buf->last_buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1045
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1046 return frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1047 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1048
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1049
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1050 static ngx_inline ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1051 ngx_http_v2_filter_send(ngx_connection_t *fc, ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1052 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1053 stream->blocked = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1054
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1055 if (ngx_http_v2_send_output_queue(stream->connection) == NGX_ERROR) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1056 fc->error = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1057 return NGX_ERROR;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1058 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1059
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1060 stream->blocked = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1061
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1062 if (stream->queued) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1063 fc->buffered |= NGX_HTTP_V2_BUFFERED;
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1064 fc->write->active = 1;
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1065 fc->write->ready = 0;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1066 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1067 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1068
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1069 fc->buffered &= ~NGX_HTTP_V2_BUFFERED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1070
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1071 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1072 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1073
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1074
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1075 static ngx_inline ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1076 ngx_http_v2_flow_control(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1077 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1078 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1079 if (stream->send_window <= 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1080 stream->exhausted = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1081 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1082 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1083
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1084 if (h2c->send_window == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1085 ngx_http_v2_waiting_queue(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1086 return NGX_DECLINED;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1087 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1088
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1089 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1090 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1091
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1092
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1093 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1094 ngx_http_v2_waiting_queue(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1095 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1096 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1097 ngx_queue_t *q;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1098 ngx_http_v2_stream_t *s;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1099
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1100 if (stream->handled) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1101 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1102 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1103
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1104 stream->handled = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1105
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1106 for (q = ngx_queue_last(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1107 q != ngx_queue_sentinel(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1108 q = ngx_queue_prev(q))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1109 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1110 s = ngx_queue_data(q, ngx_http_v2_stream_t, queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1111
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1112 if (s->node->rank < stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1113 || (s->node->rank == stream->node->rank
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1114 && s->node->rel_weight >= stream->node->rel_weight))
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1115 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1116 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1117 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1118 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1119
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1120 ngx_queue_insert_after(q, &stream->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1121 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1122
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1123
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1124
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1125 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1126 ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1127 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1128 {
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1129 ngx_chain_t *cl, *ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1130 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1131
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1132 stream = frame->stream;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1133 cl = frame->first;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1134
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1135 for ( ;; ) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1136 if (cl->buf->pos != cl->buf->last) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1137 frame->first = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1138
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1139 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1140 "http2:%ui HEADERS frame %p was sent partially",
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1141 stream->node->id, frame);
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1142
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1143 return NGX_AGAIN;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1144 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1145
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1146 ln = cl->next;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1147
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1148 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) {
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1149 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1150 stream->free_frame_headers = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1151
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1152 } else {
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1153 cl->next = stream->free_bufs;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1154 stream->free_bufs = cl;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1155 }
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1156
6292
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1157 if (cl == frame->last) {
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1158 break;
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1159 }
f72d3129cd35 HTTP/2: fixed handling of output HEADERS frames.
Valentin Bartenev <vbart@nginx.com>
parents: 6279
diff changeset
1160
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1161 cl = ln;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1162 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1163
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1164 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1165 "http2:%ui HEADERS frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1166 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1167
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1168 ngx_http_v2_handle_frame(stream, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1169
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1170 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1171
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1172 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1173 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1174
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1175
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1176 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1177 ngx_http_v2_data_frame_handler(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1178 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1179 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1180 ngx_buf_t *buf;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1181 ngx_chain_t *cl, *ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1182 ngx_http_v2_stream_t *stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1183
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1184 stream = frame->stream;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1185
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1186 cl = frame->first;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1187
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1188 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1189
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1190 if (cl->buf->pos != cl->buf->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1191 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1192 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1193 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1194
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1195 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1196 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1197
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1198 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1199
6293
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1200 cl->next = stream->free_frame_headers;
ec6b07be88a5 HTTP/2: reused HEADERS and CONTINUATION frames buffers.
Valentin Bartenev <vbart@nginx.com>
parents: 6292
diff changeset
1201 stream->free_frame_headers = cl;
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1202
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1203 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1204 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1205 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1206
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1207 cl = ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1208 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1209
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1210 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1211 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1212 buf = cl->buf->shadow;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1213
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1214 if (ngx_buf_in_memory(buf)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1215 buf->pos = cl->buf->pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1216 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1217
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1218 if (buf->in_file) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1219 buf->file_pos = cl->buf->file_pos;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1220 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1221 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1222
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1223 if (ngx_buf_size(cl->buf) != 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1224
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1225 if (cl != frame->first) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1226 frame->first = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1227 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1228 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1229
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1230 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1231 "http2:%ui DATA frame %p was sent partially",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1232 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1233
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1234 return NGX_AGAIN;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1235 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1236
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1237 ln = cl->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1238
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1239 if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_filter_get_shadow) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1240 cl->next = stream->free_bufs;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1241 stream->free_bufs = cl;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1242
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1243 } else {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1244 ngx_free_chain(stream->request->pool, cl);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1245 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1247 if (cl == frame->last) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1248 goto done;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1249 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1250
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1251 cl = ln;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1252 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1253
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1254 done:
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1255
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1256 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1257 "http2:%ui DATA frame %p was sent",
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1258 stream->node->id, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1259
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1260 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1261
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1262 ngx_http_v2_handle_frame(stream, frame);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1263
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1264 ngx_http_v2_handle_stream(h2c, stream);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1265
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1266 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1267 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1268
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1269
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1270 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1271 ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1272 ngx_http_v2_out_frame_t *frame)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1273 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1274 ngx_http_request_t *r;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1275
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1276 r = stream->request;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1277
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1278 r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1279
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1280 if (frame->fin) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1281 stream->out_closed = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1282 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1283
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1284 frame->next = stream->free_frames;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1285 stream->free_frames = frame;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1286
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1287 stream->queued--;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1288 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1289
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1290
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1291 static ngx_inline void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1292 ngx_http_v2_handle_stream(ngx_http_v2_connection_t *h2c,
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1293 ngx_http_v2_stream_t *stream)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1294 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1295 ngx_event_t *wev;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1296
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1297 if (stream->handled || stream->blocked || stream->exhausted) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1298 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1299 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1300
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1301 wev = stream->request->connection->write;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1302
6412
4ba91a4c66a3 HTTP/2: implemented per request timeouts (closes #626).
Valentin Bartenev <vbart@nginx.com>
parents: 6401
diff changeset
1303 if (!wev->delayed) {
6246
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1304 stream->handled = 1;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1305 ngx_queue_insert_tail(&h2c->posted, &stream->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1306 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1307 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1308
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1309
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1310 static void
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1311 ngx_http_v2_filter_cleanup(void *data)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1312 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1313 ngx_http_v2_stream_t *stream = data;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1314
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1315 size_t window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1316 ngx_http_v2_out_frame_t *frame, **fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1317 ngx_http_v2_connection_t *h2c;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1318
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1319 if (stream->handled) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1320 stream->handled = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1321 ngx_queue_remove(&stream->queue);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1322 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1323
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1324 if (stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1325 return;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1326 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1327
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1328 window = 0;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1329 h2c = stream->connection;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1330 fn = &h2c->last_out;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1331
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1332 for ( ;; ) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1333 frame = *fn;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1334
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1335 if (frame == NULL) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1336 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1337 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1338
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1339 if (frame->stream == stream && !frame->blocked) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1340 *fn = frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1341
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1342 window += frame->length;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1343
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1344 if (--stream->queued == 0) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1345 break;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1346 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1347
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1348 continue;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1349 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1350
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1351 fn = &frame->next;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1352 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1353
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1354 if (h2c->send_window == 0 && window && !ngx_queue_empty(&h2c->waiting)) {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1355 ngx_queue_add(&h2c->posted, &h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1356 ngx_queue_init(&h2c->waiting);
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1357 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1358
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1359 h2c->send_window += window;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1360 }
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1361
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1362
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1363 static ngx_int_t
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1364 ngx_http_v2_filter_init(ngx_conf_t *cf)
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1365 {
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1366 ngx_http_next_header_filter = ngx_http_top_header_filter;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1367 ngx_http_top_header_filter = ngx_http_v2_header_filter;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1368
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1369 return NGX_OK;
257b51c37c5a The HTTP/2 implementation (RFC 7240, 7241).
Valentin Bartenev <vbart@nginx.com>
parents:
diff changeset
1370 }