3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
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
,
19 static ngx_int_t
ngx_http_test_expect(ngx_http_request_t
*r
);
21 static ngx_int_t
ngx_http_request_body_filter(ngx_http_request_t
*r
,
23 static ngx_int_t
ngx_http_request_body_length_filter(ngx_http_request_t
*r
,
25 static ngx_int_t
ngx_http_request_body_chunked_filter(ngx_http_request_t
*r
,
27 static ngx_int_t
ngx_http_request_body_save_filter(ngx_http_request_t
*r
,
32 ngx_http_read_client_request_body(ngx_http_request_t
*r
,
33 ngx_http_client_body_handler_pt post_handler
)
40 ngx_http_request_body_t
*rb
;
41 ngx_http_core_loc_conf_t
*clcf
;
47 rc
= ngx_http_spdy_read_request_body(r
, post_handler
);
52 if (r
!= r
->main
|| r
->request_body
|| r
->discard_body
) {
57 if (ngx_http_test_expect(r
) != NGX_OK
) {
58 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
62 rb
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_request_body_t
));
64 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
69 * set by ngx_pcalloc():
79 rb
->post_handler
= post_handler
;
83 if (r
->headers_in
.content_length_n
< 0 && !r
->headers_in
.chunked
) {
88 preread
= r
->header_in
->last
- r
->header_in
->pos
;
92 /* there is the pre-read part of the request body */
94 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
95 "http client request body preread %uz", preread
);
97 out
.buf
= r
->header_in
;
100 rc
= ngx_http_request_body_filter(r
, &out
);
106 r
->request_length
+= preread
- (r
->header_in
->last
- r
->header_in
->pos
);
108 if (!r
->headers_in
.chunked
110 && rb
->rest
<= (off_t
) (r
->header_in
->end
- r
->header_in
->last
))
112 /* the whole request body may be placed in r->header_in */
114 b
= ngx_calloc_buf(r
->pool
);
116 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
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
;
128 r
->read_event_handler
= ngx_http_read_client_request_body_handler
;
129 r
->write_event_handler
= ngx_http_request_empty_handler
;
131 rc
= ngx_http_do_read_client_request_body(r
);
138 if (ngx_http_request_body_filter(r
, NULL
) != NGX_OK
) {
139 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
145 /* the whole request body was pre-read */
147 if (r
->request_body_in_file_only
) {
148 if (ngx_http_write_request_body(r
) != NGX_OK
) {
149 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
153 cl
= ngx_chain_get_free_buf(r
->pool
, &rb
->free
);
155 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
160 ngx_memzero(b
, sizeof(ngx_buf_t
));
163 b
->file_last
= rb
->temp_file
->file
.offset
;
164 b
->file
= &rb
->temp_file
->file
;
175 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
176 "negative request body rest");
177 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
181 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
183 size
= clcf
->client_body_buffer_size
;
186 /* TODO: honor r->request_body_in_single_buf */
188 if (!r
->headers_in
.chunked
&& rb
->rest
< size
) {
189 size
= (ssize_t
) rb
->rest
;
191 if (r
->request_body_in_single_buf
) {
196 size
= clcf
->client_body_buffer_size
;
199 rb
->buf
= ngx_create_temp_buf(r
->pool
, size
);
200 if (rb
->buf
== NULL
) {
201 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
205 r
->read_event_handler
= ngx_http_read_client_request_body_handler
;
206 r
->write_event_handler
= ngx_http_request_empty_handler
;
208 rc
= ngx_http_do_read_client_request_body(r
);
212 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
) {
221 ngx_http_read_client_request_body_handler(ngx_http_request_t
*r
)
225 if (r
->connection
->read
->timedout
) {
226 r
->connection
->timedout
= 1;
227 ngx_http_finalize_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
231 rc
= ngx_http_do_read_client_request_body(r
);
233 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
) {
234 ngx_http_finalize_request(r
, rc
);
240 ngx_http_do_read_client_request_body(ngx_http_request_t
*r
)
247 ngx_chain_t
*cl
, out
;
249 ngx_http_request_body_t
*rb
;
250 ngx_http_core_loc_conf_t
*clcf
;
253 rb
= r
->request_body
;
255 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
256 "http read client request body");
260 if (rb
->buf
->last
== rb
->buf
->end
) {
262 /* pass buffer to request body filter chain */
267 rc
= ngx_http_request_body_filter(r
, &out
);
275 if (ngx_http_write_request_body(r
) != NGX_OK
) {
276 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
281 rc
= ngx_http_request_body_filter(r
, NULL
);
287 if (rb
->busy
!= NULL
) {
288 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
291 rb
->buf
->pos
= rb
->buf
->start
;
292 rb
->buf
->last
= rb
->buf
->start
;
295 size
= rb
->buf
->end
- rb
->buf
->last
;
296 rest
= rb
->rest
- (rb
->buf
->last
- rb
->buf
->pos
);
298 if ((off_t
) size
> rest
) {
299 size
= (size_t) rest
;
302 n
= c
->recv(c
, rb
->buf
->last
, size
);
304 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
305 "http client request body recv %z", n
);
307 if (n
== NGX_AGAIN
) {
312 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
313 "client prematurely closed connection");
316 if (n
== 0 || n
== NGX_ERROR
) {
318 return NGX_HTTP_BAD_REQUEST
;
322 r
->request_length
+= n
;
325 /* pass buffer to request body filter chain */
330 rc
= ngx_http_request_body_filter(r
, &out
);
341 if (rb
->buf
->last
< rb
->buf
->end
) {
346 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
347 "http client request body rest %O", rb
->rest
);
353 if (!c
->read
->ready
) {
354 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
355 ngx_add_timer(c
->read
, clcf
->client_body_timeout
);
357 if (ngx_handle_read_event(c
->read
, 0) != NGX_OK
) {
358 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
365 if (c
->read
->timer_set
) {
366 ngx_del_timer(c
->read
);
369 if (rb
->temp_file
|| r
->request_body_in_file_only
) {
371 /* save the last part */
373 if (ngx_http_write_request_body(r
) != NGX_OK
) {
374 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
377 cl
= ngx_chain_get_free_buf(r
->pool
, &rb
->free
);
379 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
384 ngx_memzero(b
, sizeof(ngx_buf_t
));
387 b
->file_last
= rb
->temp_file
->file
.offset
;
388 b
->file
= &rb
->temp_file
->file
;
393 r
->read_event_handler
= ngx_http_block_reading
;
402 ngx_http_write_request_body(ngx_http_request_t
*r
)
407 ngx_http_request_body_t
*rb
;
408 ngx_http_core_loc_conf_t
*clcf
;
410 rb
= r
->request_body
;
412 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
413 "http write client request body, bufs %p", rb
->bufs
);
415 if (rb
->temp_file
== NULL
) {
416 tf
= ngx_pcalloc(r
->pool
, sizeof(ngx_temp_file_t
));
421 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
423 tf
->file
.fd
= NGX_INVALID_FILE
;
424 tf
->file
.log
= r
->connection
->log
;
425 tf
->path
= clcf
->client_body_temp_path
;
427 tf
->warn
= "a client request body is buffered to a temporary file";
428 tf
->log_level
= r
->request_body_file_log_level
;
429 tf
->persistent
= r
->request_body_in_persistent_file
;
430 tf
->clean
= r
->request_body_in_clean_file
;
432 if (r
->request_body_file_group_access
) {
438 if (rb
->bufs
== NULL
) {
439 /* empty body with r->request_body_in_file_only */
441 if (ngx_create_temp_file(&tf
->file
, tf
->path
, tf
->pool
,
442 tf
->persistent
, tf
->clean
, tf
->access
)
452 if (rb
->bufs
== NULL
) {
456 n
= ngx_write_chain_to_temp_file(rb
->temp_file
, rb
->bufs
);
458 /* TODO: n == 0 or not complete and level event */
460 if (n
== NGX_ERROR
) {
464 rb
->temp_file
->offset
+= n
;
466 /* mark all buffers as written */
468 for (cl
= rb
->bufs
; cl
; cl
= cl
->next
) {
469 cl
->buf
->pos
= cl
->buf
->last
;
479 ngx_http_discard_request_body(ngx_http_request_t
*r
)
486 if (r
->spdy_stream
&& r
== r
->main
) {
487 r
->spdy_stream
->skip_data
= NGX_SPDY_DATA_DISCARD
;
492 if (r
!= r
->main
|| r
->discard_body
|| r
->request_body
) {
496 if (ngx_http_test_expect(r
) != NGX_OK
) {
497 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
500 rev
= r
->connection
->read
;
502 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0, "http set discard body");
504 if (rev
->timer_set
) {
508 if (r
->headers_in
.content_length_n
<= 0 && !r
->headers_in
.chunked
) {
512 size
= r
->header_in
->last
- r
->header_in
->pos
;
514 if (size
|| r
->headers_in
.chunked
) {
515 rc
= ngx_http_discard_request_body_filter(r
, r
->header_in
);
521 if (r
->headers_in
.content_length_n
== 0) {
526 rc
= ngx_http_read_discarded_request_body(r
);
529 r
->lingering_close
= 0;
533 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
) {
537 /* rc == NGX_AGAIN */
539 r
->read_event_handler
= ngx_http_discarded_request_body_handler
;
541 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
542 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
553 ngx_http_discarded_request_body_handler(ngx_http_request_t
*r
)
559 ngx_http_core_loc_conf_t
*clcf
;
567 ngx_http_finalize_request(r
, NGX_ERROR
);
571 if (r
->lingering_time
) {
572 timer
= (ngx_msec_t
) (r
->lingering_time
- ngx_time());
576 r
->lingering_close
= 0;
577 ngx_http_finalize_request(r
, NGX_ERROR
);
585 rc
= ngx_http_read_discarded_request_body(r
);
589 r
->lingering_close
= 0;
590 ngx_http_finalize_request(r
, NGX_DONE
);
594 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
) {
596 ngx_http_finalize_request(r
, NGX_ERROR
);
600 /* rc == NGX_AGAIN */
602 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
604 ngx_http_finalize_request(r
, NGX_ERROR
);
610 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
614 if (timer
> clcf
->lingering_timeout
) {
615 timer
= clcf
->lingering_timeout
;
618 ngx_add_timer(rev
, timer
);
624 ngx_http_read_discarded_request_body(ngx_http_request_t
*r
)
630 u_char buffer
[NGX_HTTP_DISCARD_BUFFER_SIZE
];
632 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
633 "http read discarded body");
635 ngx_memzero(&b
, sizeof(ngx_buf_t
));
640 if (r
->headers_in
.content_length_n
== 0) {
641 r
->read_event_handler
= ngx_http_block_reading
;
645 if (!r
->connection
->read
->ready
) {
649 size
= (size_t) ngx_min(r
->headers_in
.content_length_n
,
650 NGX_HTTP_DISCARD_BUFFER_SIZE
);
652 n
= r
->connection
->recv(r
->connection
, buffer
, size
);
654 if (n
== NGX_ERROR
) {
655 r
->connection
->error
= 1;
659 if (n
== NGX_AGAIN
) {
670 rc
= ngx_http_discard_request_body_filter(r
, &b
);
680 ngx_http_discard_request_body_filter(ngx_http_request_t
*r
, ngx_buf_t
*b
)
684 ngx_http_request_body_t
*rb
;
686 if (r
->headers_in
.chunked
) {
688 rb
= r
->request_body
;
692 rb
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_request_body_t
));
694 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
697 rb
->chunked
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_chunked_t
));
698 if (rb
->chunked
== NULL
) {
699 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
702 r
->request_body
= rb
;
707 rc
= ngx_http_parse_chunked(r
, b
, rb
->chunked
);
711 /* a chunk has been parsed successfully */
713 size
= b
->last
- b
->pos
;
715 if ((off_t
) size
> rb
->chunked
->size
) {
716 b
->pos
+= rb
->chunked
->size
;
717 rb
->chunked
->size
= 0;
720 rb
->chunked
->size
-= size
;
727 if (rc
== NGX_DONE
) {
729 /* a whole response has been parsed successfully */
731 r
->headers_in
.content_length_n
= 0;
735 if (rc
== NGX_AGAIN
) {
737 /* set amount of data we want to see next time */
739 r
->headers_in
.content_length_n
= rb
->chunked
->length
;
745 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
746 "client sent invalid chunked body");
748 return NGX_HTTP_BAD_REQUEST
;
752 size
= b
->last
- b
->pos
;
754 if ((off_t
) size
> r
->headers_in
.content_length_n
) {
755 b
->pos
+= r
->headers_in
.content_length_n
;
756 r
->headers_in
.content_length_n
= 0;
760 r
->headers_in
.content_length_n
-= size
;
769 ngx_http_test_expect(ngx_http_request_t
*r
)
775 || r
->headers_in
.expect
== NULL
776 || r
->http_version
< NGX_HTTP_VERSION_11
)
781 r
->expect_tested
= 1;
783 expect
= &r
->headers_in
.expect
->value
;
785 if (expect
->len
!= sizeof("100-continue") - 1
786 || ngx_strncasecmp(expect
->data
, (u_char
*) "100-continue",
787 sizeof("100-continue") - 1)
793 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
794 "send 100 Continue");
796 n
= r
->connection
->send(r
->connection
,
797 (u_char
*) "HTTP/1.1 100 Continue" CRLF CRLF
,
798 sizeof("HTTP/1.1 100 Continue" CRLF CRLF
) - 1);
800 if (n
== sizeof("HTTP/1.1 100 Continue" CRLF CRLF
) - 1) {
804 /* we assume that such small packet should be send successfully */
811 ngx_http_request_body_filter(ngx_http_request_t
*r
, ngx_chain_t
*in
)
813 if (r
->headers_in
.chunked
) {
814 return ngx_http_request_body_chunked_filter(r
, in
);
817 return ngx_http_request_body_length_filter(r
, in
);
823 ngx_http_request_body_length_filter(ngx_http_request_t
*r
, ngx_chain_t
*in
)
828 ngx_chain_t
*cl
, *tl
, *out
, **ll
;
829 ngx_http_request_body_t
*rb
;
831 rb
= r
->request_body
;
833 if (rb
->rest
== -1) {
834 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
835 "http request body content length filter");
837 rb
->rest
= r
->headers_in
.content_length_n
;
843 for (cl
= in
; cl
; cl
= cl
->next
) {
845 tl
= ngx_chain_get_free_buf(r
->pool
, &rb
->free
);
847 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
852 ngx_memzero(b
, sizeof(ngx_buf_t
));
855 b
->tag
= (ngx_buf_tag_t
) &ngx_http_read_client_request_body
;
856 b
->start
= cl
->buf
->pos
;
857 b
->pos
= cl
->buf
->pos
;
858 b
->last
= cl
->buf
->last
;
859 b
->end
= cl
->buf
->end
;
861 size
= cl
->buf
->last
- cl
->buf
->pos
;
863 if ((off_t
) size
< rb
->rest
) {
864 cl
->buf
->pos
= cl
->buf
->last
;
868 cl
->buf
->pos
+= rb
->rest
;
870 b
->last
= cl
->buf
->pos
;
878 rc
= ngx_http_request_body_save_filter(r
, out
);
880 ngx_chain_update_chains(r
->pool
, &rb
->free
, &rb
->busy
, &out
,
881 (ngx_buf_tag_t
) &ngx_http_read_client_request_body
);
888 ngx_http_request_body_chunked_filter(ngx_http_request_t
*r
, ngx_chain_t
*in
)
893 ngx_chain_t
*cl
, *out
, *tl
, **ll
;
894 ngx_http_request_body_t
*rb
;
895 ngx_http_core_loc_conf_t
*clcf
;
897 rb
= r
->request_body
;
899 if (rb
->rest
== -1) {
901 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
902 "http request body chunked filter");
904 rb
->chunked
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_chunked_t
));
905 if (rb
->chunked
== NULL
) {
906 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
909 r
->headers_in
.content_length_n
= 0;
916 for (cl
= in
; cl
; cl
= cl
->next
) {
920 ngx_log_debug7(NGX_LOG_DEBUG_EVENT
, r
->connection
->log
, 0,
921 "http body chunked buf "
922 "t:%d f:%d %p, pos %p, size: %z file: %O, size: %z",
923 cl
->buf
->temporary
, cl
->buf
->in_file
,
924 cl
->buf
->start
, cl
->buf
->pos
,
925 cl
->buf
->last
- cl
->buf
->pos
,
927 cl
->buf
->file_last
- cl
->buf
->file_pos
);
929 rc
= ngx_http_parse_chunked(r
, cl
->buf
, rb
->chunked
);
933 /* a chunk has been parsed successfully */
935 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
937 if (clcf
->client_max_body_size
938 && clcf
->client_max_body_size
939 < r
->headers_in
.content_length_n
+ rb
->chunked
->size
)
941 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
942 "client intended to send too large chunked "
944 r
->headers_in
.content_length_n
945 + rb
->chunked
->size
);
947 r
->lingering_close
= 1;
949 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE
;
952 tl
= ngx_chain_get_free_buf(r
->pool
, &rb
->free
);
954 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
959 ngx_memzero(b
, sizeof(ngx_buf_t
));
962 b
->tag
= (ngx_buf_tag_t
) &ngx_http_read_client_request_body
;
963 b
->start
= cl
->buf
->pos
;
964 b
->pos
= cl
->buf
->pos
;
965 b
->last
= cl
->buf
->last
;
966 b
->end
= cl
->buf
->end
;
971 size
= cl
->buf
->last
- cl
->buf
->pos
;
973 if ((off_t
) size
> rb
->chunked
->size
) {
974 cl
->buf
->pos
+= rb
->chunked
->size
;
975 r
->headers_in
.content_length_n
+= rb
->chunked
->size
;
976 rb
->chunked
->size
= 0;
979 rb
->chunked
->size
-= size
;
980 r
->headers_in
.content_length_n
+= size
;
981 cl
->buf
->pos
= cl
->buf
->last
;
984 b
->last
= cl
->buf
->pos
;
989 if (rc
== NGX_DONE
) {
991 /* a whole response has been parsed successfully */
995 tl
= ngx_chain_get_free_buf(r
->pool
, &rb
->free
);
997 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
1002 ngx_memzero(b
, sizeof(ngx_buf_t
));
1012 if (rc
== NGX_AGAIN
) {
1014 /* set rb->rest, amount of data we want to see next time */
1016 rb
->rest
= rb
->chunked
->length
;
1023 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
1024 "client sent invalid chunked body");
1026 return NGX_HTTP_BAD_REQUEST
;
1030 rc
= ngx_http_request_body_save_filter(r
, out
);
1032 ngx_chain_update_chains(r
->pool
, &rb
->free
, &rb
->busy
, &out
,
1033 (ngx_buf_tag_t
) &ngx_http_read_client_request_body
);
1040 ngx_http_request_body_save_filter(ngx_http_request_t
*r
, ngx_chain_t
*in
)
1045 ngx_http_request_body_t
*rb
;
1047 rb
= r
->request_body
;
1051 for (cl
= rb
->bufs
; cl
; cl
= cl
->next
) {
1052 ngx_log_debug7(NGX_LOG_DEBUG_EVENT
, r
->connection
->log
, 0,
1053 "http body old buf t:%d f:%d %p, pos %p, size: %z "
1054 "file: %O, size: %z",
1055 cl
->buf
->temporary
, cl
->buf
->in_file
,
1056 cl
->buf
->start
, cl
->buf
->pos
,
1057 cl
->buf
->last
- cl
->buf
->pos
,
1059 cl
->buf
->file_last
- cl
->buf
->file_pos
);
1062 for (cl
= in
; cl
; cl
= cl
->next
) {
1063 ngx_log_debug7(NGX_LOG_DEBUG_EVENT
, r
->connection
->log
, 0,
1064 "http body new buf t:%d f:%d %p, pos %p, size: %z "
1065 "file: %O, size: %z",
1066 cl
->buf
->temporary
, cl
->buf
->in_file
,
1067 cl
->buf
->start
, cl
->buf
->pos
,
1068 cl
->buf
->last
- cl
->buf
->pos
,
1070 cl
->buf
->file_last
- cl
->buf
->file_pos
);
1075 /* TODO: coalesce neighbouring buffers */
1077 if (ngx_chain_add_copy(r
->pool
, &rb
->bufs
, in
) != NGX_OK
) {
1078 return NGX_HTTP_INTERNAL_SERVER_ERROR
;