Mercurial > hg > nginx
comparison src/stream/ngx_stream_core_module.c @ 6694:ea9dfe2f62e7
Stream: preread phase.
In this phase, head of a stream is read and analysed before proceeding to the
content phase. Amount of data read is controlled by the module implementing
the phase, but not more than defined by the "preread_buffer_size" directive.
The time spent on processing preread is controlled by the "preread_timeout"
directive.
The typical preread phase module will parse the beginning of a stream and set
variable that may be used by the content phase, for example to make routing
decision.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 15 Sep 2016 14:56:02 +0300 |
parents | 3908156a51fa |
children | cebf5fed00bf |
comparison
equal
deleted
inserted
replaced
6693:3908156a51fa | 6694:ea9dfe2f62e7 |
---|---|
89 ngx_conf_set_flag_slot, | 89 ngx_conf_set_flag_slot, |
90 NGX_STREAM_SRV_CONF_OFFSET, | 90 NGX_STREAM_SRV_CONF_OFFSET, |
91 offsetof(ngx_stream_core_srv_conf_t, tcp_nodelay), | 91 offsetof(ngx_stream_core_srv_conf_t, tcp_nodelay), |
92 NULL }, | 92 NULL }, |
93 | 93 |
94 { ngx_string("preread_buffer_size"), | |
95 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
96 ngx_conf_set_size_slot, | |
97 NGX_STREAM_SRV_CONF_OFFSET, | |
98 offsetof(ngx_stream_core_srv_conf_t, preread_buffer_size), | |
99 NULL }, | |
100 | |
101 { ngx_string("preread_timeout"), | |
102 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
103 ngx_conf_set_msec_slot, | |
104 NGX_STREAM_SRV_CONF_OFFSET, | |
105 offsetof(ngx_stream_core_srv_conf_t, preread_timeout), | |
106 NULL }, | |
107 | |
94 ngx_null_command | 108 ngx_null_command |
95 }; | 109 }; |
96 | 110 |
97 | 111 |
98 static ngx_stream_module_t ngx_stream_core_module_ctx = { | 112 static ngx_stream_module_t ngx_stream_core_module_ctx = { |
151 { | 165 { |
152 ngx_int_t rc; | 166 ngx_int_t rc; |
153 | 167 |
154 /* | 168 /* |
155 * generic phase checker, | 169 * generic phase checker, |
156 * used by all phases, except for content | 170 * used by all phases, except for preread and content |
157 */ | 171 */ |
158 | 172 |
159 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | 173 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, |
160 "generic phase: %ui", s->phase_handler); | 174 "generic phase: %ui", s->phase_handler); |
161 | 175 |
170 s->phase_handler++; | 184 s->phase_handler++; |
171 return NGX_AGAIN; | 185 return NGX_AGAIN; |
172 } | 186 } |
173 | 187 |
174 if (rc == NGX_AGAIN || rc == NGX_DONE) { | 188 if (rc == NGX_AGAIN || rc == NGX_DONE) { |
189 return NGX_OK; | |
190 } | |
191 | |
192 if (rc == NGX_ERROR) { | |
193 rc = NGX_STREAM_INTERNAL_SERVER_ERROR; | |
194 } | |
195 | |
196 ngx_stream_finalize_session(s, rc); | |
197 | |
198 return NGX_OK; | |
199 } | |
200 | |
201 | |
202 ngx_int_t | |
203 ngx_stream_core_preread_phase(ngx_stream_session_t *s, | |
204 ngx_stream_phase_handler_t *ph) | |
205 { | |
206 size_t size; | |
207 ssize_t n; | |
208 ngx_int_t rc; | |
209 ngx_connection_t *c; | |
210 ngx_stream_core_srv_conf_t *cscf; | |
211 | |
212 c = s->connection; | |
213 | |
214 c->log->action = "prereading client data"; | |
215 | |
216 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
217 | |
218 if (c->read->timedout) { | |
219 rc = NGX_STREAM_OK; | |
220 | |
221 } else if (c->read->timer_set) { | |
222 rc = NGX_AGAIN; | |
223 | |
224 } else { | |
225 rc = ph->handler(s); | |
226 } | |
227 | |
228 while (rc == NGX_AGAIN) { | |
229 | |
230 if (c->buffer == NULL) { | |
231 c->buffer = ngx_create_temp_buf(c->pool, cscf->preread_buffer_size); | |
232 if (c->buffer == NULL) { | |
233 rc = NGX_ERROR; | |
234 break; | |
235 } | |
236 } | |
237 | |
238 size = c->buffer->end - c->buffer->last; | |
239 | |
240 if (size == 0) { | |
241 ngx_log_error(NGX_LOG_ERR, c->log, 0, "preread buffer full"); | |
242 rc = NGX_STREAM_BAD_REQUEST; | |
243 break; | |
244 } | |
245 | |
246 if (c->read->eof) { | |
247 rc = NGX_STREAM_OK; | |
248 break; | |
249 } | |
250 | |
251 if (!c->read->ready) { | |
252 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { | |
253 rc = NGX_ERROR; | |
254 break; | |
255 } | |
256 | |
257 if (!c->read->timer_set) { | |
258 ngx_add_timer(c->read, cscf->preread_timeout); | |
259 } | |
260 | |
261 c->read->handler = ngx_stream_session_handler; | |
262 | |
263 return NGX_OK; | |
264 } | |
265 | |
266 n = c->recv(c, c->buffer->last, size); | |
267 | |
268 if (n == NGX_ERROR) { | |
269 rc = NGX_STREAM_OK; | |
270 break; | |
271 } | |
272 | |
273 if (n > 0) { | |
274 c->buffer->last += n; | |
275 } | |
276 | |
277 rc = ph->handler(s); | |
278 } | |
279 | |
280 if (c->read->timer_set) { | |
281 ngx_del_timer(c->read); | |
282 } | |
283 | |
284 if (rc == NGX_OK) { | |
285 s->phase_handler = ph->next; | |
286 return NGX_AGAIN; | |
287 } | |
288 | |
289 if (rc == NGX_DECLINED) { | |
290 s->phase_handler++; | |
291 return NGX_AGAIN; | |
292 } | |
293 | |
294 if (rc == NGX_DONE) { | |
175 return NGX_OK; | 295 return NGX_OK; |
176 } | 296 } |
177 | 297 |
178 if (rc == NGX_ERROR) { | 298 if (rc == NGX_ERROR) { |
179 rc = NGX_STREAM_INTERNAL_SERVER_ERROR; | 299 rc = NGX_STREAM_INTERNAL_SERVER_ERROR; |
301 cscf->file_name = cf->conf_file->file.name.data; | 421 cscf->file_name = cf->conf_file->file.name.data; |
302 cscf->line = cf->conf_file->line; | 422 cscf->line = cf->conf_file->line; |
303 cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; | 423 cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; |
304 cscf->proxy_protocol_timeout = NGX_CONF_UNSET_MSEC; | 424 cscf->proxy_protocol_timeout = NGX_CONF_UNSET_MSEC; |
305 cscf->tcp_nodelay = NGX_CONF_UNSET; | 425 cscf->tcp_nodelay = NGX_CONF_UNSET; |
426 cscf->preread_buffer_size = NGX_CONF_UNSET_SIZE; | |
427 cscf->preread_timeout = NGX_CONF_UNSET_MSEC; | |
306 | 428 |
307 return cscf; | 429 return cscf; |
308 } | 430 } |
309 | 431 |
310 | 432 |
352 | 474 |
353 ngx_conf_merge_msec_value(conf->proxy_protocol_timeout, | 475 ngx_conf_merge_msec_value(conf->proxy_protocol_timeout, |
354 prev->proxy_protocol_timeout, 30000); | 476 prev->proxy_protocol_timeout, 30000); |
355 | 477 |
356 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1); | 478 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1); |
479 | |
480 ngx_conf_merge_size_value(conf->preread_buffer_size, | |
481 prev->preread_buffer_size, 16384); | |
482 | |
483 ngx_conf_merge_msec_value(conf->preread_timeout, | |
484 prev->preread_timeout, 30000); | |
357 | 485 |
358 return NGX_CONF_OK; | 486 return NGX_CONF_OK; |
359 } | 487 } |
360 | 488 |
361 | 489 |