File: | http/ngx_http_request_body.c |
Location: | line 1141, column 13 |
Description: | Dereference of null pointer |
1 | ||||
2 | /* | |||
3 | * Copyright (C) Igor Sysoev | |||
4 | * Copyright (C) Nginx, Inc. | |||
5 | */ | |||
6 | ||||
7 | ||||
8 | #include <ngx_config.h> | |||
9 | #include <ngx_core.h> | |||
10 | #include <ngx_http.h> | |||
11 | ||||
12 | ||||
13 | static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r); | |||
14 | static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r); | |||
15 | static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r); | |||
16 | static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r); | |||
17 | static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r, | |||
18 | ngx_buf_t *b); | |||
19 | static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r); | |||
20 | ||||
21 | static ngx_int_t ngx_http_request_body_filter(ngx_http_request_t *r, | |||
22 | ngx_chain_t *in); | |||
23 | static ngx_int_t ngx_http_request_body_length_filter(ngx_http_request_t *r, | |||
24 | ngx_chain_t *in); | |||
25 | static ngx_int_t ngx_http_request_body_chunked_filter(ngx_http_request_t *r, | |||
26 | ngx_chain_t *in); | |||
27 | ||||
28 | ||||
29 | ngx_int_t | |||
30 | ngx_http_read_client_request_body(ngx_http_request_t *r, | |||
31 | ngx_http_client_body_handler_pt post_handler) | |||
32 | { | |||
33 | size_t preread; | |||
34 | ssize_t size; | |||
35 | ngx_int_t rc; | |||
36 | ngx_buf_t *b; | |||
37 | ngx_chain_t out; | |||
38 | ngx_http_request_body_t *rb; | |||
39 | ngx_http_core_loc_conf_t *clcf; | |||
40 | ||||
41 | r->main->count++; | |||
42 | ||||
43 | if (r != r->main || r->request_body || r->discard_body) { | |||
44 | r->request_body_no_buffering = 0; | |||
45 | post_handler(r); | |||
46 | return NGX_OK0; | |||
47 | } | |||
48 | ||||
49 | #if (NGX_HTTP_V2) | |||
50 | if (r->stream) { | |||
51 | rc = ngx_http_v2_read_request_body(r, post_handler); | |||
52 | goto done; | |||
53 | } | |||
54 | #endif | |||
55 | ||||
56 | if (ngx_http_test_expect(r) != NGX_OK0) { | |||
57 | rc = NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
58 | goto done; | |||
59 | } | |||
60 | ||||
61 | rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); | |||
62 | if (rb == NULL((void*)0)) { | |||
63 | rc = NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
64 | goto done; | |||
65 | } | |||
66 | ||||
67 | /* | |||
68 | * set by ngx_pcalloc(): | |||
69 | * | |||
70 | * rb->bufs = NULL; | |||
71 | * rb->buf = NULL; | |||
72 | * rb->free = NULL; | |||
73 | * rb->busy = NULL; | |||
74 | * rb->chunked = NULL; | |||
75 | */ | |||
76 | ||||
77 | rb->rest = -1; | |||
78 | rb->post_handler = post_handler; | |||
79 | ||||
80 | r->request_body = rb; | |||
81 | ||||
82 | if (r->headers_in.content_length_n < 0 && !r->headers_in.chunked) { | |||
83 | r->request_body_no_buffering = 0; | |||
84 | post_handler(r); | |||
85 | return NGX_OK0; | |||
86 | } | |||
87 | ||||
88 | preread = r->header_in->last - r->header_in->pos; | |||
89 | ||||
90 | if (preread) { | |||
91 | ||||
92 | /* there is the pre-read part of the request body */ | |||
93 | ||||
94 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |||
95 | "http client request body preread %uz", preread); | |||
96 | ||||
97 | out.buf = r->header_in; | |||
98 | out.next = NULL((void*)0); | |||
99 | ||||
100 | rc = ngx_http_request_body_filter(r, &out); | |||
101 | ||||
102 | if (rc != NGX_OK0) { | |||
103 | goto done; | |||
104 | } | |||
105 | ||||
106 | r->request_length += preread - (r->header_in->last - r->header_in->pos); | |||
107 | ||||
108 | if (!r->headers_in.chunked | |||
109 | && rb->rest > 0 | |||
110 | && rb->rest <= (off_t) (r->header_in->end - r->header_in->last)) | |||
111 | { | |||
112 | /* the whole request body may be placed in r->header_in */ | |||
113 | ||||
114 | b = ngx_calloc_buf(r->pool)ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |||
115 | if (b == NULL((void*)0)) { | |||
116 | rc = NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
117 | goto done; | |||
118 | } | |||
119 | ||||
120 | b->temporary = 1; | |||
121 | b->start = r->header_in->pos; | |||
122 | b->pos = r->header_in->pos; | |||
123 | b->last = r->header_in->last; | |||
124 | b->end = r->header_in->end; | |||
125 | ||||
126 | rb->buf = b; | |||
127 | ||||
128 | r->read_event_handler = ngx_http_read_client_request_body_handler; | |||
129 | r->write_event_handler = ngx_http_request_empty_handler; | |||
130 | ||||
131 | rc = ngx_http_do_read_client_request_body(r); | |||
132 | goto done; | |||
133 | } | |||
134 | ||||
135 | } else { | |||
136 | /* set rb->rest */ | |||
137 | ||||
138 | if (ngx_http_request_body_filter(r, NULL((void*)0)) != NGX_OK0) { | |||
139 | rc = NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
140 | goto done; | |||
141 | } | |||
142 | } | |||
143 | ||||
144 | if (rb->rest == 0) { | |||
145 | /* the whole request body was pre-read */ | |||
146 | r->request_body_no_buffering = 0; | |||
147 | post_handler(r); | |||
148 | return NGX_OK0; | |||
149 | } | |||
150 | ||||
151 | if (rb->rest < 0) { | |||
152 | ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,if ((r->connection->log)->log_level >= 2) ngx_log_error_core (2, r->connection->log, 0, "negative request body rest" ) | |||
153 | "negative request body rest")if ((r->connection->log)->log_level >= 2) ngx_log_error_core (2, r->connection->log, 0, "negative request body rest" ); | |||
154 | rc = NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
155 | goto done; | |||
156 | } | |||
157 | ||||
158 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module)(r)->loc_conf[ngx_http_core_module.ctx_index]; | |||
159 | ||||
160 | size = clcf->client_body_buffer_size; | |||
161 | size += size >> 2; | |||
162 | ||||
163 | /* TODO: honor r->request_body_in_single_buf */ | |||
164 | ||||
165 | if (!r->headers_in.chunked && rb->rest < size) { | |||
166 | size = (ssize_t) rb->rest; | |||
167 | ||||
168 | if (r->request_body_in_single_buf) { | |||
169 | size += preread; | |||
170 | } | |||
171 | ||||
172 | } else { | |||
173 | size = clcf->client_body_buffer_size; | |||
174 | } | |||
175 | ||||
176 | rb->buf = ngx_create_temp_buf(r->pool, size); | |||
177 | if (rb->buf == NULL((void*)0)) { | |||
178 | rc = NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
179 | goto done; | |||
180 | } | |||
181 | ||||
182 | r->read_event_handler = ngx_http_read_client_request_body_handler; | |||
183 | r->write_event_handler = ngx_http_request_empty_handler; | |||
184 | ||||
185 | rc = ngx_http_do_read_client_request_body(r); | |||
186 | ||||
187 | done: | |||
188 | ||||
189 | if (r->request_body_no_buffering | |||
190 | && (rc == NGX_OK0 || rc == NGX_AGAIN-2)) | |||
191 | { | |||
192 | if (rc == NGX_OK0) { | |||
193 | r->request_body_no_buffering = 0; | |||
194 | ||||
195 | } else { | |||
196 | /* rc == NGX_AGAIN */ | |||
197 | r->reading_body = 1; | |||
198 | } | |||
199 | ||||
200 | r->read_event_handler = ngx_http_block_reading; | |||
201 | post_handler(r); | |||
202 | } | |||
203 | ||||
204 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE300) { | |||
205 | r->main->count--; | |||
206 | } | |||
207 | ||||
208 | return rc; | |||
209 | } | |||
210 | ||||
211 | ||||
212 | ngx_int_t | |||
213 | ngx_http_read_unbuffered_request_body(ngx_http_request_t *r) | |||
214 | { | |||
215 | ngx_int_t rc; | |||
216 | ||||
217 | #if (NGX_HTTP_V2) | |||
218 | if (r->stream) { | |||
219 | rc = ngx_http_v2_read_unbuffered_request_body(r); | |||
220 | ||||
221 | if (rc == NGX_OK0) { | |||
222 | r->reading_body = 0; | |||
223 | } | |||
224 | ||||
225 | return rc; | |||
226 | } | |||
227 | #endif | |||
228 | ||||
229 | if (r->connection->read->timedout) { | |||
230 | r->connection->timedout = 1; | |||
231 | return NGX_HTTP_REQUEST_TIME_OUT408; | |||
232 | } | |||
233 | ||||
234 | rc = ngx_http_do_read_client_request_body(r); | |||
235 | ||||
236 | if (rc == NGX_OK0) { | |||
237 | r->reading_body = 0; | |||
238 | } | |||
239 | ||||
240 | return rc; | |||
241 | } | |||
242 | ||||
243 | ||||
244 | static void | |||
245 | ngx_http_read_client_request_body_handler(ngx_http_request_t *r) | |||
246 | { | |||
247 | ngx_int_t rc; | |||
248 | ||||
249 | if (r->connection->read->timedout) { | |||
250 | r->connection->timedout = 1; | |||
251 | ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT408); | |||
252 | return; | |||
253 | } | |||
254 | ||||
255 | rc = ngx_http_do_read_client_request_body(r); | |||
256 | ||||
257 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE300) { | |||
258 | ngx_http_finalize_request(r, rc); | |||
259 | } | |||
260 | } | |||
261 | ||||
262 | ||||
263 | static ngx_int_t | |||
264 | ngx_http_do_read_client_request_body(ngx_http_request_t *r) | |||
265 | { | |||
266 | off_t rest; | |||
267 | size_t size; | |||
268 | ssize_t n; | |||
269 | ngx_int_t rc; | |||
270 | ngx_chain_t out; | |||
271 | ngx_connection_t *c; | |||
272 | ngx_http_request_body_t *rb; | |||
273 | ngx_http_core_loc_conf_t *clcf; | |||
274 | ||||
275 | c = r->connection; | |||
276 | rb = r->request_body; | |||
277 | ||||
278 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |||
279 | "http read client request body"); | |||
280 | ||||
281 | for ( ;; ) { | |||
282 | for ( ;; ) { | |||
283 | if (rb->buf->last == rb->buf->end) { | |||
284 | ||||
285 | if (rb->buf->pos != rb->buf->last) { | |||
286 | ||||
287 | /* pass buffer to request body filter chain */ | |||
288 | ||||
289 | out.buf = rb->buf; | |||
290 | out.next = NULL((void*)0); | |||
291 | ||||
292 | rc = ngx_http_request_body_filter(r, &out); | |||
293 | ||||
294 | if (rc != NGX_OK0) { | |||
295 | return rc; | |||
296 | } | |||
297 | ||||
298 | } else { | |||
299 | ||||
300 | /* update chains */ | |||
301 | ||||
302 | rc = ngx_http_request_body_filter(r, NULL((void*)0)); | |||
303 | ||||
304 | if (rc != NGX_OK0) { | |||
305 | return rc; | |||
306 | } | |||
307 | } | |||
308 | ||||
309 | if (rb->busy != NULL((void*)0)) { | |||
310 | if (r->request_body_no_buffering) { | |||
311 | if (c->read->timer_set) { | |||
312 | ngx_del_timerngx_event_del_timer(c->read); | |||
313 | } | |||
314 | ||||
315 | if (ngx_handle_read_event(c->read, 0) != NGX_OK0) { | |||
316 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
317 | } | |||
318 | ||||
319 | return NGX_AGAIN-2; | |||
320 | } | |||
321 | ||||
322 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
323 | } | |||
324 | ||||
325 | rb->buf->pos = rb->buf->start; | |||
326 | rb->buf->last = rb->buf->start; | |||
327 | } | |||
328 | ||||
329 | size = rb->buf->end - rb->buf->last; | |||
330 | rest = rb->rest - (rb->buf->last - rb->buf->pos); | |||
331 | ||||
332 | if ((off_t) size > rest) { | |||
333 | size = (size_t) rest; | |||
334 | } | |||
335 | ||||
336 | n = c->recv(c, rb->buf->last, size); | |||
337 | ||||
338 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |||
339 | "http client request body recv %z", n); | |||
340 | ||||
341 | if (n == NGX_AGAIN-2) { | |||
342 | break; | |||
343 | } | |||
344 | ||||
345 | if (n == 0) { | |||
346 | ngx_log_error(NGX_LOG_INFO, c->log, 0,if ((c->log)->log_level >= 7) ngx_log_error_core(7, c ->log, 0, "client prematurely closed connection") | |||
347 | "client prematurely closed connection")if ((c->log)->log_level >= 7) ngx_log_error_core(7, c ->log, 0, "client prematurely closed connection"); | |||
348 | } | |||
349 | ||||
350 | if (n == 0 || n == NGX_ERROR-1) { | |||
351 | c->error = 1; | |||
352 | return NGX_HTTP_BAD_REQUEST400; | |||
353 | } | |||
354 | ||||
355 | rb->buf->last += n; | |||
356 | r->request_length += n; | |||
357 | ||||
358 | if (n == rest) { | |||
359 | /* pass buffer to request body filter chain */ | |||
360 | ||||
361 | out.buf = rb->buf; | |||
362 | out.next = NULL((void*)0); | |||
363 | ||||
364 | rc = ngx_http_request_body_filter(r, &out); | |||
365 | ||||
366 | if (rc != NGX_OK0) { | |||
367 | return rc; | |||
368 | } | |||
369 | } | |||
370 | ||||
371 | if (rb->rest == 0) { | |||
372 | break; | |||
373 | } | |||
374 | ||||
375 | if (rb->buf->last < rb->buf->end) { | |||
376 | break; | |||
377 | } | |||
378 | } | |||
379 | ||||
380 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |||
381 | "http client request body rest %O", rb->rest); | |||
382 | ||||
383 | if (rb->rest == 0) { | |||
384 | break; | |||
385 | } | |||
386 | ||||
387 | if (!c->read->ready) { | |||
388 | ||||
389 | if (r->request_body_no_buffering | |||
390 | && rb->buf->pos != rb->buf->last) | |||
391 | { | |||
392 | /* pass buffer to request body filter chain */ | |||
393 | ||||
394 | out.buf = rb->buf; | |||
395 | out.next = NULL((void*)0); | |||
396 | ||||
397 | rc = ngx_http_request_body_filter(r, &out); | |||
398 | ||||
399 | if (rc != NGX_OK0) { | |||
400 | return rc; | |||
401 | } | |||
402 | } | |||
403 | ||||
404 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module)(r)->loc_conf[ngx_http_core_module.ctx_index]; | |||
405 | ngx_add_timerngx_event_add_timer(c->read, clcf->client_body_timeout); | |||
406 | ||||
407 | if (ngx_handle_read_event(c->read, 0) != NGX_OK0) { | |||
408 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
409 | } | |||
410 | ||||
411 | return NGX_AGAIN-2; | |||
412 | } | |||
413 | } | |||
414 | ||||
415 | if (c->read->timer_set) { | |||
416 | ngx_del_timerngx_event_del_timer(c->read); | |||
417 | } | |||
418 | ||||
419 | if (!r->request_body_no_buffering) { | |||
420 | r->read_event_handler = ngx_http_block_reading; | |||
421 | rb->post_handler(r); | |||
422 | } | |||
423 | ||||
424 | return NGX_OK0; | |||
425 | } | |||
426 | ||||
427 | ||||
428 | static ngx_int_t | |||
429 | ngx_http_write_request_body(ngx_http_request_t *r) | |||
430 | { | |||
431 | ssize_t n; | |||
432 | ngx_chain_t *cl, *ln; | |||
433 | ngx_temp_file_t *tf; | |||
434 | ngx_http_request_body_t *rb; | |||
435 | ngx_http_core_loc_conf_t *clcf; | |||
436 | ||||
437 | rb = r->request_body; | |||
438 | ||||
439 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |||
440 | "http write client request body, bufs %p", rb->bufs); | |||
441 | ||||
442 | if (rb->temp_file == NULL((void*)0)) { | |||
443 | tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); | |||
444 | if (tf == NULL((void*)0)) { | |||
445 | return NGX_ERROR-1; | |||
446 | } | |||
447 | ||||
448 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module)(r)->loc_conf[ngx_http_core_module.ctx_index]; | |||
449 | ||||
450 | tf->file.fd = NGX_INVALID_FILE-1; | |||
451 | tf->file.log = r->connection->log; | |||
452 | tf->path = clcf->client_body_temp_path; | |||
453 | tf->pool = r->pool; | |||
454 | tf->warn = "a client request body is buffered to a temporary file"; | |||
455 | tf->log_level = r->request_body_file_log_level; | |||
456 | tf->persistent = r->request_body_in_persistent_file; | |||
457 | tf->clean = r->request_body_in_clean_file; | |||
458 | ||||
459 | if (r->request_body_file_group_access) { | |||
460 | tf->access = 0660; | |||
461 | } | |||
462 | ||||
463 | rb->temp_file = tf; | |||
464 | ||||
465 | if (rb->bufs == NULL((void*)0)) { | |||
466 | /* empty body with r->request_body_in_file_only */ | |||
467 | ||||
468 | if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, | |||
469 | tf->persistent, tf->clean, tf->access) | |||
470 | != NGX_OK0) | |||
471 | { | |||
472 | return NGX_ERROR-1; | |||
473 | } | |||
474 | ||||
475 | return NGX_OK0; | |||
476 | } | |||
477 | } | |||
478 | ||||
479 | if (rb->bufs == NULL((void*)0)) { | |||
480 | return NGX_OK0; | |||
481 | } | |||
482 | ||||
483 | n = ngx_write_chain_to_temp_file(rb->temp_file, rb->bufs); | |||
484 | ||||
485 | /* TODO: n == 0 or not complete and level event */ | |||
486 | ||||
487 | if (n == NGX_ERROR-1) { | |||
488 | return NGX_ERROR-1; | |||
489 | } | |||
490 | ||||
491 | rb->temp_file->offset += n; | |||
492 | ||||
493 | /* mark all buffers as written */ | |||
494 | ||||
495 | for (cl = rb->bufs; cl; /* void */) { | |||
496 | ||||
497 | cl->buf->pos = cl->buf->last; | |||
498 | ||||
499 | ln = cl; | |||
500 | cl = cl->next; | |||
501 | ngx_free_chain(r->pool, ln)ln->next = r->pool->chain; r->pool->chain = ln; | |||
502 | } | |||
503 | ||||
504 | rb->bufs = NULL((void*)0); | |||
505 | ||||
506 | return NGX_OK0; | |||
507 | } | |||
508 | ||||
509 | ||||
510 | ngx_int_t | |||
511 | ngx_http_discard_request_body(ngx_http_request_t *r) | |||
512 | { | |||
513 | ssize_t size; | |||
514 | ngx_int_t rc; | |||
515 | ngx_event_t *rev; | |||
516 | ||||
517 | if (r != r->main || r->discard_body || r->request_body) { | |||
518 | return NGX_OK0; | |||
519 | } | |||
520 | ||||
521 | #if (NGX_HTTP_V2) | |||
522 | if (r->stream) { | |||
523 | r->stream->skip_data = 1; | |||
524 | return NGX_OK0; | |||
525 | } | |||
526 | #endif | |||
527 | ||||
528 | if (ngx_http_test_expect(r) != NGX_OK0) { | |||
529 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
530 | } | |||
531 | ||||
532 | rev = r->connection->read; | |||
533 | ||||
534 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body"); | |||
535 | ||||
536 | if (rev->timer_set) { | |||
537 | ngx_del_timerngx_event_del_timer(rev); | |||
538 | } | |||
539 | ||||
540 | if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { | |||
541 | return NGX_OK0; | |||
542 | } | |||
543 | ||||
544 | size = r->header_in->last - r->header_in->pos; | |||
545 | ||||
546 | if (size || r->headers_in.chunked) { | |||
547 | rc = ngx_http_discard_request_body_filter(r, r->header_in); | |||
548 | ||||
549 | if (rc != NGX_OK0) { | |||
550 | return rc; | |||
551 | } | |||
552 | ||||
553 | if (r->headers_in.content_length_n == 0) { | |||
554 | return NGX_OK0; | |||
555 | } | |||
556 | } | |||
557 | ||||
558 | rc = ngx_http_read_discarded_request_body(r); | |||
559 | ||||
560 | if (rc == NGX_OK0) { | |||
561 | r->lingering_close = 0; | |||
562 | return NGX_OK0; | |||
563 | } | |||
564 | ||||
565 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE300) { | |||
566 | return rc; | |||
567 | } | |||
568 | ||||
569 | /* rc == NGX_AGAIN */ | |||
570 | ||||
571 | r->read_event_handler = ngx_http_discarded_request_body_handler; | |||
572 | ||||
573 | if (ngx_handle_read_event(rev, 0) != NGX_OK0) { | |||
574 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
575 | } | |||
576 | ||||
577 | r->count++; | |||
578 | r->discard_body = 1; | |||
579 | ||||
580 | return NGX_OK0; | |||
581 | } | |||
582 | ||||
583 | ||||
584 | void | |||
585 | ngx_http_discarded_request_body_handler(ngx_http_request_t *r) | |||
586 | { | |||
587 | ngx_int_t rc; | |||
588 | ngx_msec_t timer; | |||
589 | ngx_event_t *rev; | |||
590 | ngx_connection_t *c; | |||
591 | ngx_http_core_loc_conf_t *clcf; | |||
592 | ||||
593 | c = r->connection; | |||
594 | rev = c->read; | |||
595 | ||||
596 | if (rev->timedout) { | |||
597 | c->timedout = 1; | |||
598 | c->error = 1; | |||
599 | ngx_http_finalize_request(r, NGX_ERROR-1); | |||
600 | return; | |||
601 | } | |||
602 | ||||
603 | if (r->lingering_time) { | |||
604 | timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time()ngx_cached_time->sec; | |||
605 | ||||
606 | if ((ngx_msec_int_t) timer <= 0) { | |||
607 | r->discard_body = 0; | |||
608 | r->lingering_close = 0; | |||
609 | ngx_http_finalize_request(r, NGX_ERROR-1); | |||
610 | return; | |||
611 | } | |||
612 | ||||
613 | } else { | |||
614 | timer = 0; | |||
615 | } | |||
616 | ||||
617 | rc = ngx_http_read_discarded_request_body(r); | |||
618 | ||||
619 | if (rc == NGX_OK0) { | |||
620 | r->discard_body = 0; | |||
621 | r->lingering_close = 0; | |||
622 | ngx_http_finalize_request(r, NGX_DONE-4); | |||
623 | return; | |||
624 | } | |||
625 | ||||
626 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE300) { | |||
627 | c->error = 1; | |||
628 | ngx_http_finalize_request(r, NGX_ERROR-1); | |||
629 | return; | |||
630 | } | |||
631 | ||||
632 | /* rc == NGX_AGAIN */ | |||
633 | ||||
634 | if (ngx_handle_read_event(rev, 0) != NGX_OK0) { | |||
635 | c->error = 1; | |||
636 | ngx_http_finalize_request(r, NGX_ERROR-1); | |||
637 | return; | |||
638 | } | |||
639 | ||||
640 | if (timer) { | |||
641 | ||||
642 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module)(r)->loc_conf[ngx_http_core_module.ctx_index]; | |||
643 | ||||
644 | timer *= 1000; | |||
645 | ||||
646 | if (timer > clcf->lingering_timeout) { | |||
647 | timer = clcf->lingering_timeout; | |||
648 | } | |||
649 | ||||
650 | ngx_add_timerngx_event_add_timer(rev, timer); | |||
651 | } | |||
652 | } | |||
653 | ||||
654 | ||||
655 | static ngx_int_t | |||
656 | ngx_http_read_discarded_request_body(ngx_http_request_t *r) | |||
657 | { | |||
658 | size_t size; | |||
659 | ssize_t n; | |||
660 | ngx_int_t rc; | |||
661 | ngx_buf_t b; | |||
662 | u_char buffer[NGX_HTTP_DISCARD_BUFFER_SIZE4096]; | |||
663 | ||||
664 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |||
665 | "http read discarded body"); | |||
666 | ||||
667 | ngx_memzero(&b, sizeof(ngx_buf_t))(void) memset(&b, 0, sizeof(ngx_buf_t)); | |||
668 | ||||
669 | b.temporary = 1; | |||
670 | ||||
671 | for ( ;; ) { | |||
672 | if (r->headers_in.content_length_n == 0) { | |||
673 | r->read_event_handler = ngx_http_block_reading; | |||
674 | return NGX_OK0; | |||
675 | } | |||
676 | ||||
677 | if (!r->connection->read->ready) { | |||
678 | return NGX_AGAIN-2; | |||
679 | } | |||
680 | ||||
681 | size = (size_t) ngx_min(r->headers_in.content_length_n,((r->headers_in.content_length_n > 4096) ? (4096) : (r-> headers_in.content_length_n)) | |||
682 | NGX_HTTP_DISCARD_BUFFER_SIZE)((r->headers_in.content_length_n > 4096) ? (4096) : (r-> headers_in.content_length_n)); | |||
683 | ||||
684 | n = r->connection->recv(r->connection, buffer, size); | |||
685 | ||||
686 | if (n == NGX_ERROR-1) { | |||
687 | r->connection->error = 1; | |||
688 | return NGX_OK0; | |||
689 | } | |||
690 | ||||
691 | if (n == NGX_AGAIN-2) { | |||
692 | return NGX_AGAIN-2; | |||
693 | } | |||
694 | ||||
695 | if (n == 0) { | |||
696 | return NGX_OK0; | |||
697 | } | |||
698 | ||||
699 | b.pos = buffer; | |||
700 | b.last = buffer + n; | |||
701 | ||||
702 | rc = ngx_http_discard_request_body_filter(r, &b); | |||
703 | ||||
704 | if (rc != NGX_OK0) { | |||
705 | return rc; | |||
706 | } | |||
707 | } | |||
708 | } | |||
709 | ||||
710 | ||||
711 | static ngx_int_t | |||
712 | ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b) | |||
713 | { | |||
714 | size_t size; | |||
715 | ngx_int_t rc; | |||
716 | ngx_http_request_body_t *rb; | |||
717 | ||||
718 | if (r->headers_in.chunked) { | |||
719 | ||||
720 | rb = r->request_body; | |||
721 | ||||
722 | if (rb == NULL((void*)0)) { | |||
723 | ||||
724 | rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); | |||
725 | if (rb == NULL((void*)0)) { | |||
726 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
727 | } | |||
728 | ||||
729 | rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t)); | |||
730 | if (rb->chunked == NULL((void*)0)) { | |||
731 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
732 | } | |||
733 | ||||
734 | r->request_body = rb; | |||
735 | } | |||
736 | ||||
737 | for ( ;; ) { | |||
738 | ||||
739 | rc = ngx_http_parse_chunked(r, b, rb->chunked); | |||
740 | ||||
741 | if (rc == NGX_OK0) { | |||
742 | ||||
743 | /* a chunk has been parsed successfully */ | |||
744 | ||||
745 | size = b->last - b->pos; | |||
746 | ||||
747 | if ((off_t) size > rb->chunked->size) { | |||
748 | b->pos += (size_t) rb->chunked->size; | |||
749 | rb->chunked->size = 0; | |||
750 | ||||
751 | } else { | |||
752 | rb->chunked->size -= size; | |||
753 | b->pos = b->last; | |||
754 | } | |||
755 | ||||
756 | continue; | |||
757 | } | |||
758 | ||||
759 | if (rc == NGX_DONE-4) { | |||
760 | ||||
761 | /* a whole response has been parsed successfully */ | |||
762 | ||||
763 | r->headers_in.content_length_n = 0; | |||
764 | break; | |||
765 | } | |||
766 | ||||
767 | if (rc == NGX_AGAIN-2) { | |||
768 | ||||
769 | /* set amount of data we want to see next time */ | |||
770 | ||||
771 | r->headers_in.content_length_n = rb->chunked->length; | |||
772 | break; | |||
773 | } | |||
774 | ||||
775 | /* invalid */ | |||
776 | ||||
777 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client sent invalid chunked body" ) | |||
778 | "client sent invalid chunked body")if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client sent invalid chunked body" ); | |||
779 | ||||
780 | return NGX_HTTP_BAD_REQUEST400; | |||
781 | } | |||
782 | ||||
783 | } else { | |||
784 | size = b->last - b->pos; | |||
785 | ||||
786 | if ((off_t) size > r->headers_in.content_length_n) { | |||
787 | b->pos += (size_t) r->headers_in.content_length_n; | |||
788 | r->headers_in.content_length_n = 0; | |||
789 | ||||
790 | } else { | |||
791 | b->pos = b->last; | |||
792 | r->headers_in.content_length_n -= size; | |||
793 | } | |||
794 | } | |||
795 | ||||
796 | return NGX_OK0; | |||
797 | } | |||
798 | ||||
799 | ||||
800 | static ngx_int_t | |||
801 | ngx_http_test_expect(ngx_http_request_t *r) | |||
802 | { | |||
803 | ngx_int_t n; | |||
804 | ngx_str_t *expect; | |||
805 | ||||
806 | if (r->expect_tested | |||
807 | || r->headers_in.expect == NULL((void*)0) | |||
808 | || r->http_version < NGX_HTTP_VERSION_111001) | |||
809 | { | |||
810 | return NGX_OK0; | |||
811 | } | |||
812 | ||||
813 | r->expect_tested = 1; | |||
814 | ||||
815 | expect = &r->headers_in.expect->value; | |||
816 | ||||
817 | if (expect->len != sizeof("100-continue") - 1 | |||
818 | || ngx_strncasecmp(expect->data, (u_char *) "100-continue", | |||
819 | sizeof("100-continue") - 1) | |||
820 | != 0) | |||
821 | { | |||
822 | return NGX_OK0; | |||
823 | } | |||
824 | ||||
825 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |||
826 | "send 100 Continue"); | |||
827 | ||||
828 | n = r->connection->send(r->connection, | |||
829 | (u_char *) "HTTP/1.1 100 Continue" CRLF"\r\n" CRLF"\r\n", | |||
830 | sizeof("HTTP/1.1 100 Continue" CRLF"\r\n" CRLF"\r\n") - 1); | |||
831 | ||||
832 | if (n == sizeof("HTTP/1.1 100 Continue" CRLF"\r\n" CRLF"\r\n") - 1) { | |||
833 | return NGX_OK0; | |||
834 | } | |||
835 | ||||
836 | /* we assume that such small packet should be send successfully */ | |||
837 | ||||
838 | return NGX_ERROR-1; | |||
839 | } | |||
840 | ||||
841 | ||||
842 | static ngx_int_t | |||
843 | ngx_http_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |||
844 | { | |||
845 | if (r->headers_in.chunked) { | |||
846 | return ngx_http_request_body_chunked_filter(r, in); | |||
847 | ||||
848 | } else { | |||
849 | return ngx_http_request_body_length_filter(r, in); | |||
850 | } | |||
851 | } | |||
852 | ||||
853 | ||||
854 | static ngx_int_t | |||
855 | ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in) | |||
856 | { | |||
857 | size_t size; | |||
858 | ngx_int_t rc; | |||
859 | ngx_buf_t *b; | |||
860 | ngx_chain_t *cl, *tl, *out, **ll; | |||
861 | ngx_http_request_body_t *rb; | |||
862 | ||||
863 | rb = r->request_body; | |||
864 | ||||
865 | if (rb->rest == -1) { | |||
866 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |||
867 | "http request body content length filter"); | |||
868 | ||||
869 | rb->rest = r->headers_in.content_length_n; | |||
870 | } | |||
871 | ||||
872 | out = NULL((void*)0); | |||
873 | ll = &out; | |||
874 | ||||
875 | for (cl = in; cl; cl = cl->next) { | |||
876 | ||||
877 | if (rb->rest == 0) { | |||
878 | break; | |||
879 | } | |||
880 | ||||
881 | tl = ngx_chain_get_free_buf(r->pool, &rb->free); | |||
882 | if (tl == NULL((void*)0)) { | |||
883 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
884 | } | |||
885 | ||||
886 | b = tl->buf; | |||
887 | ||||
888 | ngx_memzero(b, sizeof(ngx_buf_t))(void) memset(b, 0, sizeof(ngx_buf_t)); | |||
889 | ||||
890 | b->temporary = 1; | |||
891 | b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body; | |||
892 | b->start = cl->buf->pos; | |||
893 | b->pos = cl->buf->pos; | |||
894 | b->last = cl->buf->last; | |||
895 | b->end = cl->buf->end; | |||
896 | b->flush = r->request_body_no_buffering; | |||
897 | ||||
898 | size = cl->buf->last - cl->buf->pos; | |||
899 | ||||
900 | if ((off_t) size < rb->rest) { | |||
901 | cl->buf->pos = cl->buf->last; | |||
902 | rb->rest -= size; | |||
903 | ||||
904 | } else { | |||
905 | cl->buf->pos += (size_t) rb->rest; | |||
906 | rb->rest = 0; | |||
907 | b->last = cl->buf->pos; | |||
908 | b->last_buf = 1; | |||
909 | } | |||
910 | ||||
911 | *ll = tl; | |||
912 | ll = &tl->next; | |||
913 | } | |||
914 | ||||
915 | rc = ngx_http_top_request_body_filter(r, out); | |||
916 | ||||
917 | ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out, | |||
918 | (ngx_buf_tag_t) &ngx_http_read_client_request_body); | |||
919 | ||||
920 | return rc; | |||
921 | } | |||
922 | ||||
923 | ||||
924 | static ngx_int_t | |||
925 | ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in) | |||
926 | { | |||
927 | size_t size; | |||
928 | ngx_int_t rc; | |||
929 | ngx_buf_t *b; | |||
930 | ngx_chain_t *cl, *out, *tl, **ll; | |||
931 | ngx_http_request_body_t *rb; | |||
932 | ngx_http_core_loc_conf_t *clcf; | |||
933 | ||||
934 | rb = r->request_body; | |||
935 | ||||
936 | if (rb->rest == -1) { | |||
937 | ||||
938 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |||
939 | "http request body chunked filter"); | |||
940 | ||||
941 | rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t)); | |||
942 | if (rb->chunked == NULL((void*)0)) { | |||
943 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
944 | } | |||
945 | ||||
946 | r->headers_in.content_length_n = 0; | |||
947 | rb->rest = 3; | |||
948 | } | |||
949 | ||||
950 | out = NULL((void*)0); | |||
951 | ll = &out; | |||
952 | ||||
953 | for (cl = in; cl; cl = cl->next) { | |||
954 | ||||
955 | for ( ;; ) { | |||
956 | ||||
957 | ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, | |||
958 | "http body chunked buf " | |||
959 | "t:%d f:%d %p, pos %p, size: %z file: %O, size: %O", | |||
960 | cl->buf->temporary, cl->buf->in_file, | |||
961 | cl->buf->start, cl->buf->pos, | |||
962 | cl->buf->last - cl->buf->pos, | |||
963 | cl->buf->file_pos, | |||
964 | cl->buf->file_last - cl->buf->file_pos); | |||
965 | ||||
966 | rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked); | |||
967 | ||||
968 | if (rc == NGX_OK0) { | |||
969 | ||||
970 | /* a chunk has been parsed successfully */ | |||
971 | ||||
972 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module)(r)->loc_conf[ngx_http_core_module.ctx_index]; | |||
973 | ||||
974 | if (clcf->client_max_body_size | |||
975 | && clcf->client_max_body_size | |||
976 | - r->headers_in.content_length_n < rb->chunked->size) | |||
977 | { | |||
978 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client intended to send too large chunked " "body: %O+%O bytes", r->headers_in.content_length_n, rb-> chunked->size) | |||
979 | "client intended to send too large chunked "if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client intended to send too large chunked " "body: %O+%O bytes", r->headers_in.content_length_n, rb-> chunked->size) | |||
980 | "body: %O+%O bytes",if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client intended to send too large chunked " "body: %O+%O bytes", r->headers_in.content_length_n, rb-> chunked->size) | |||
981 | r->headers_in.content_length_n,if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client intended to send too large chunked " "body: %O+%O bytes", r->headers_in.content_length_n, rb-> chunked->size) | |||
982 | rb->chunked->size)if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client intended to send too large chunked " "body: %O+%O bytes", r->headers_in.content_length_n, rb-> chunked->size); | |||
983 | ||||
984 | r->lingering_close = 1; | |||
985 | ||||
986 | return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE413; | |||
987 | } | |||
988 | ||||
989 | tl = ngx_chain_get_free_buf(r->pool, &rb->free); | |||
990 | if (tl == NULL((void*)0)) { | |||
991 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
992 | } | |||
993 | ||||
994 | b = tl->buf; | |||
995 | ||||
996 | ngx_memzero(b, sizeof(ngx_buf_t))(void) memset(b, 0, sizeof(ngx_buf_t)); | |||
997 | ||||
998 | b->temporary = 1; | |||
999 | b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body; | |||
1000 | b->start = cl->buf->pos; | |||
1001 | b->pos = cl->buf->pos; | |||
1002 | b->last = cl->buf->last; | |||
1003 | b->end = cl->buf->end; | |||
1004 | b->flush = r->request_body_no_buffering; | |||
1005 | ||||
1006 | *ll = tl; | |||
1007 | ll = &tl->next; | |||
1008 | ||||
1009 | size = cl->buf->last - cl->buf->pos; | |||
1010 | ||||
1011 | if ((off_t) size > rb->chunked->size) { | |||
1012 | cl->buf->pos += (size_t) rb->chunked->size; | |||
1013 | r->headers_in.content_length_n += rb->chunked->size; | |||
1014 | rb->chunked->size = 0; | |||
1015 | ||||
1016 | } else { | |||
1017 | rb->chunked->size -= size; | |||
1018 | r->headers_in.content_length_n += size; | |||
1019 | cl->buf->pos = cl->buf->last; | |||
1020 | } | |||
1021 | ||||
1022 | b->last = cl->buf->pos; | |||
1023 | ||||
1024 | continue; | |||
1025 | } | |||
1026 | ||||
1027 | if (rc == NGX_DONE-4) { | |||
1028 | ||||
1029 | /* a whole response has been parsed successfully */ | |||
1030 | ||||
1031 | rb->rest = 0; | |||
1032 | ||||
1033 | tl = ngx_chain_get_free_buf(r->pool, &rb->free); | |||
1034 | if (tl == NULL((void*)0)) { | |||
1035 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
1036 | } | |||
1037 | ||||
1038 | b = tl->buf; | |||
1039 | ||||
1040 | ngx_memzero(b, sizeof(ngx_buf_t))(void) memset(b, 0, sizeof(ngx_buf_t)); | |||
1041 | ||||
1042 | b->last_buf = 1; | |||
1043 | ||||
1044 | *ll = tl; | |||
1045 | ll = &tl->next; | |||
1046 | ||||
1047 | break; | |||
1048 | } | |||
1049 | ||||
1050 | if (rc == NGX_AGAIN-2) { | |||
1051 | ||||
1052 | /* set rb->rest, amount of data we want to see next time */ | |||
1053 | ||||
1054 | rb->rest = rb->chunked->length; | |||
1055 | ||||
1056 | break; | |||
1057 | } | |||
1058 | ||||
1059 | /* invalid */ | |||
1060 | ||||
1061 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client sent invalid chunked body" ) | |||
1062 | "client sent invalid chunked body")if ((r->connection->log)->log_level >= 4) ngx_log_error_core (4, r->connection->log, 0, "client sent invalid chunked body" ); | |||
1063 | ||||
1064 | return NGX_HTTP_BAD_REQUEST400; | |||
1065 | } | |||
1066 | } | |||
1067 | ||||
1068 | rc = ngx_http_top_request_body_filter(r, out); | |||
1069 | ||||
1070 | ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out, | |||
1071 | (ngx_buf_tag_t) &ngx_http_read_client_request_body); | |||
1072 | ||||
1073 | return rc; | |||
1074 | } | |||
1075 | ||||
1076 | ||||
1077 | ngx_int_t | |||
1078 | ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) | |||
1079 | { | |||
1080 | ngx_buf_t *b; | |||
1081 | ngx_chain_t *cl; | |||
1082 | ngx_http_request_body_t *rb; | |||
1083 | ||||
1084 | rb = r->request_body; | |||
1085 | ||||
1086 | #if (NGX_DEBUG) | |||
1087 | ||||
1088 | for (cl = rb->bufs; cl; cl = cl->next) { | |||
1089 | ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, | |||
1090 | "http body old buf t:%d f:%d %p, pos %p, size: %z " | |||
1091 | "file: %O, size: %O", | |||
1092 | cl->buf->temporary, cl->buf->in_file, | |||
1093 | cl->buf->start, cl->buf->pos, | |||
1094 | cl->buf->last - cl->buf->pos, | |||
1095 | cl->buf->file_pos, | |||
1096 | cl->buf->file_last - cl->buf->file_pos); | |||
1097 | } | |||
1098 | ||||
1099 | for (cl = in; cl; cl = cl->next) { | |||
1100 | ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, | |||
1101 | "http body new buf t:%d f:%d %p, pos %p, size: %z " | |||
1102 | "file: %O, size: %O", | |||
1103 | cl->buf->temporary, cl->buf->in_file, | |||
1104 | cl->buf->start, cl->buf->pos, | |||
1105 | cl->buf->last - cl->buf->pos, | |||
1106 | cl->buf->file_pos, | |||
1107 | cl->buf->file_last - cl->buf->file_pos); | |||
1108 | } | |||
1109 | ||||
1110 | #endif | |||
1111 | ||||
1112 | /* TODO: coalesce neighbouring buffers */ | |||
1113 | ||||
1114 | if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK0) { | |||
| ||||
1115 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
1116 | } | |||
1117 | ||||
1118 | if (r->request_body_no_buffering) { | |||
1119 | return NGX_OK0; | |||
1120 | } | |||
1121 | ||||
1122 | if (rb->rest > 0) { | |||
1123 | ||||
1124 | if (rb->buf && rb->buf->last == rb->buf->end | |||
1125 | && ngx_http_write_request_body(r) != NGX_OK0) | |||
1126 | { | |||
1127 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
1128 | } | |||
1129 | ||||
1130 | return NGX_OK0; | |||
1131 | } | |||
1132 | ||||
1133 | /* rb->rest == 0 */ | |||
1134 | ||||
1135 | if (rb->temp_file || r->request_body_in_file_only) { | |||
1136 | ||||
1137 | if (ngx_http_write_request_body(r) != NGX_OK0) { | |||
1138 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
1139 | } | |||
1140 | ||||
1141 | if (rb->temp_file->file.offset != 0) { | |||
| ||||
1142 | ||||
1143 | cl = ngx_chain_get_free_buf(r->pool, &rb->free); | |||
1144 | if (cl == NULL((void*)0)) { | |||
1145 | return NGX_HTTP_INTERNAL_SERVER_ERROR500; | |||
1146 | } | |||
1147 | ||||
1148 | b = cl->buf; | |||
1149 | ||||
1150 | ngx_memzero(b, sizeof(ngx_buf_t))(void) memset(b, 0, sizeof(ngx_buf_t)); | |||
1151 | ||||
1152 | b->in_file = 1; | |||
1153 | b->file_last = rb->temp_file->file.offset; | |||
1154 | b->file = &rb->temp_file->file; | |||
1155 | ||||
1156 | rb->bufs = cl; | |||
1157 | } | |||
1158 | } | |||
1159 | ||||
1160 | return NGX_OK0; | |||
1161 | } |