comparison src/http/ngx_http_spdy.h @ 5121:c0f7b94e88ba

Preliminary experimental support for SPDY draft 2.
author Valentin Bartenev <vbart@nginx.com>
date Wed, 20 Mar 2013 10:36:57 +0000
parents
children 15a7deeaa19a
comparison
equal deleted inserted replaced
5120:7956af6b6a02 5121:c0f7b94e88ba
1 /*
2 * Copyright (C) Nginx, Inc.
3 * Copyright (C) Valentin V. Bartenev
4 */
5
6
7 #ifndef _NGX_HTTP_SPDY_H_INCLUDED_
8 #define _NGX_HTTP_SPDY_H_INCLUDED_
9
10
11 #include <ngx_config.h>
12 #include <ngx_core.h>
13 #include <ngx_http.h>
14
15 #include <zlib.h>
16
17
18 #define NGX_SPDY_VERSION 2
19
20 #ifdef TLSEXT_TYPE_next_proto_neg
21 #define NGX_SPDY_NPN_ADVERTISE "\x06spdy/2"
22 #define NGX_SPDY_NPN_NEGOTIATED "spdy/2"
23 #endif
24
25 #define NGX_SPDY_STATE_BUFFER_SIZE 16
26
27 #define NGX_SPDY_CTL_BIT 1
28
29 #define NGX_SPDY_SYN_STREAM 1
30 #define NGX_SPDY_SYN_REPLY 2
31 #define NGX_SPDY_RST_STREAM 3
32 #define NGX_SPDY_SETTINGS 4
33 #define NGX_SPDY_NOOP 5
34 #define NGX_SPDY_PING 6
35 #define NGX_SPDY_GOAWAY 7
36 #define NGX_SPDY_HEADERS 8
37
38 #define NGX_SPDY_FRAME_HEADER_SIZE 8
39
40 #define NGX_SPDY_SID_SIZE 4
41
42 #define NGX_SPDY_SYN_STREAM_SIZE 10
43 #define NGX_SPDY_SYN_REPLY_SIZE 6
44 #define NGX_SPDY_RST_STREAM_SIZE 8
45 #define NGX_SPDY_PING_SIZE 4
46 #define NGX_SPDY_GOAWAY_SIZE 4
47 #define NGX_SPDY_NV_NUM_SIZE 2
48 #define NGX_SPDY_NV_NLEN_SIZE 2
49 #define NGX_SPDY_NV_VLEN_SIZE 2
50 #define NGX_SPDY_SETTINGS_NUM_SIZE 4
51 #define NGX_SPDY_SETTINGS_IDF_SIZE 4
52 #define NGX_SPDY_SETTINGS_VAL_SIZE 4
53
54 #define NGX_SPDY_SETTINGS_PAIR_SIZE \
55 (NGX_SPDY_SETTINGS_IDF_SIZE + NGX_SPDY_SETTINGS_VAL_SIZE)
56
57 #define NGX_SPDY_HIGHEST_PRIORITY 0
58 #define NGX_SPDY_LOWEST_PRIORITY 3
59
60 #define NGX_SPDY_FLAG_FIN 0x01
61 #define NGX_SPDY_FLAG_UNIDIRECTIONAL 0x02
62 #define NGX_SPDY_FLAG_CLEAR_SETTINGS 0x01
63
64 #define NGX_SPDY_MAX_FRAME_SIZE ((1 << 24) - 1)
65
66 #define NGX_SPDY_DATA_DISCARD 1
67 #define NGX_SPDY_DATA_ERROR 2
68 #define NGX_SPDY_DATA_INTERNAL_ERROR 3
69
70
71 typedef struct ngx_http_spdy_connection_s ngx_http_spdy_connection_t;
72 typedef struct ngx_http_spdy_out_frame_s ngx_http_spdy_out_frame_t;
73
74
75 typedef u_char *(*ngx_http_spdy_handler_pt) (ngx_http_spdy_connection_t *sc,
76 u_char *pos, u_char *end);
77
78 struct ngx_http_spdy_connection_s {
79 ngx_connection_t *connection;
80 ngx_http_connection_t *http_connection;
81
82 ngx_uint_t processing;
83
84 u_char buffer[NGX_SPDY_STATE_BUFFER_SIZE];
85 size_t buffer_used;
86 ngx_http_spdy_handler_pt handler;
87
88 z_stream zstream_in;
89 z_stream zstream_out;
90
91 ngx_pool_t *pool;
92
93 ngx_http_spdy_out_frame_t *free_ctl_frames;
94 ngx_connection_t *free_fake_connections;
95
96 ngx_http_spdy_stream_t **streams_index;
97
98 ngx_http_spdy_out_frame_t *last_out;
99 ngx_http_spdy_stream_t *last_stream;
100
101 ngx_http_spdy_stream_t *stream;
102
103 ngx_uint_t headers;
104 size_t length;
105 u_char flags;
106
107 ngx_uint_t last_sid;
108
109 unsigned blocked:2;
110 unsigned waiting:1; /* FIXME better name */
111 };
112
113
114 struct ngx_http_spdy_stream_s {
115 ngx_uint_t id;
116 ngx_http_request_t *request;
117 ngx_http_spdy_connection_t *connection;
118 ngx_http_spdy_stream_t *index;
119 ngx_http_spdy_stream_t *next;
120
121 ngx_uint_t header_buffers;
122 ngx_uint_t waiting;
123 ngx_http_spdy_out_frame_t *free_frames;
124 ngx_chain_t *free_data_headers;
125
126 unsigned priority:2;
127 unsigned handled:1;
128 unsigned in_closed:1;
129 unsigned out_closed:1;
130 unsigned skip_data:2;
131 };
132
133
134 struct ngx_http_spdy_out_frame_s {
135 ngx_http_spdy_out_frame_t *next;
136 ngx_chain_t *first;
137 ngx_chain_t *last;
138 ngx_int_t (*handler)(ngx_http_spdy_connection_t *sc,
139 ngx_http_spdy_out_frame_t *frame);
140
141 ngx_http_spdy_out_frame_t *free;
142
143 ngx_http_spdy_stream_t *stream;
144 size_t size;
145
146 ngx_uint_t priority;
147 unsigned blocked:1;
148 unsigned fin:1;
149 };
150
151
152 static ngx_inline void
153 ngx_http_spdy_queue_frame(ngx_http_spdy_connection_t *sc,
154 ngx_http_spdy_out_frame_t *frame)
155 {
156 ngx_http_spdy_out_frame_t **out;
157
158 for (out = &sc->last_out; *out; out = &(*out)->next)
159 {
160 if (frame->priority >= (*out)->priority) {
161 break;
162 }
163 }
164
165 frame->next = *out;
166 *out = frame;
167 }
168
169
170 static ngx_inline void
171 ngx_http_spdy_queue_blocked_frame(ngx_http_spdy_connection_t *sc,
172 ngx_http_spdy_out_frame_t *frame)
173 {
174 ngx_http_spdy_out_frame_t **out;
175
176 for (out = &sc->last_out; *out && !(*out)->blocked; out = &(*out)->next)
177 {
178 if (frame->priority >= (*out)->priority) {
179 break;
180 }
181 }
182
183 frame->next = *out;
184 *out = frame;
185 }
186
187
188 void ngx_http_spdy_init(ngx_event_t *rev);
189 void ngx_http_spdy_request_headers_init();
190
191 ngx_int_t ngx_http_spdy_read_request_body(ngx_http_request_t *r,
192 ngx_http_client_body_handler_pt post_handler);
193
194 void ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc);
195
196 ngx_int_t ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc);
197
198
199 #define ngx_spdy_frame_aligned_write_uint16(p, s) \
200 (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
201
202 #define ngx_spdy_frame_aligned_write_uint32(p, s) \
203 (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
204
205 #if (NGX_HAVE_NONALIGNED)
206
207 #define ngx_spdy_frame_write_uint16 ngx_spdy_frame_aligned_write_uint16
208 #define ngx_spdy_frame_write_uint32 ngx_spdy_frame_aligned_write_uint32
209
210 #else
211
212 #define ngx_spdy_frame_write_uint16(p, s) \
213 ((p)[0] = (u_char) (s) >> 8, (p)[1] = (u_char) (s), (p) + sizeof(uint16_t))
214
215 #define ngx_spdy_frame_write_uint32(p, s) \
216 ((p)[0] = (u_char) (s) >> 24, \
217 (p)[1] = (u_char) (s) >> 16, \
218 (p)[2] = (u_char) (s) >> 8, \
219 (p)[3] = (u_char) (s), (p) + sizeof(uint32_t))
220
221 #endif
222
223
224 #define ngx_spdy_ctl_frame_head(t) \
225 ((uint32_t) NGX_SPDY_CTL_BIT << 31 | NGX_SPDY_VERSION << 16 | (t))
226
227 #define ngx_spdy_frame_write_head(p, t) \
228 ngx_spdy_frame_aligned_write_uint32(p, ngx_spdy_ctl_frame_head(t))
229
230 #define ngx_spdy_frame_write_flags_and_len(p, f, l) \
231 ngx_spdy_frame_aligned_write_uint32(p, (f) << 24 | (l))
232
233 #define ngx_spdy_frame_write_sid ngx_spdy_frame_aligned_write_uint32
234
235 #endif /* _NGX_HTTP_SPDY_H_INCLUDED_ */