Mercurial > hg > nginx
annotate src/http/ngx_http_request_body.c @ 4937:3b6594a2b79f
Request body: block write events while reading body.
If write events are not blocked, an extra write event might happen for
various reasons (e.g. as a result of a http pipelining), resulting in
incorrect body being passed to a post handler.
The problem manifested itself with the dav module only, as this is
the only module which reads the body from a content phase handler (in
contrast to exclusive content handlers like proxy). Additionally, dav
module used to dump core in such situations due to ticket #238.
See reports here:
http://mailman.nginx.org/pipermail/nginx-devel/2012-November/002981.html
http://serverfault.com/questions/449195/nginx-webdav-server-with-auth-request
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 26 Nov 2012 18:01:49 +0000 |
parents | 240e3fb392c9 |
children | 43cb2c9799c1 |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
6 |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
83
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
8 #include <ngx_config.h> |
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
9 #include <ngx_core.h> |
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
10 #include <ngx_http.h> |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
12 |
509 | 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); | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
15 static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r); |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1369
diff
changeset
|
16 static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r); |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
17 static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
18 ngx_buf_t *b); |
2436
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
19 static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r); |
633 | 20 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
21 static ngx_int_t ngx_http_request_body_filter(ngx_http_request_t *r, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
22 ngx_chain_t *in); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
23 static ngx_int_t ngx_http_request_body_length_filter(ngx_http_request_t *r, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
24 ngx_chain_t *in); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
25 static ngx_int_t ngx_http_request_body_chunked_filter(ngx_http_request_t *r, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
26 ngx_chain_t *in); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
27 static ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
28 ngx_chain_t *in); |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
29 |
83
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
30 |
501 | 31 ngx_int_t |
32 ngx_http_read_client_request_body(ngx_http_request_t *r, | |
33 ngx_http_client_body_handler_pt post_handler) | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
34 { |
663 | 35 size_t preread; |
36 ssize_t size; | |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
37 ngx_int_t rc; |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
38 ngx_chain_t out; |
479 | 39 ngx_http_request_body_t *rb; |
303
00c5660d2707
nginx-0.0.3-2004-04-01-20:20:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
299
diff
changeset
|
40 ngx_http_core_loc_conf_t *clcf; |
297
ee394e997c77
nginx-0.0.3-2004-03-29-21:43:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
296
diff
changeset
|
41 |
3049 | 42 r->main->count++; |
43 | |
537 | 44 if (r->request_body || r->discard_body) { |
509 | 45 post_handler(r); |
46 return NGX_OK; | |
47 } | |
48 | |
2436
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
49 if (ngx_http_test_expect(r) != NGX_OK) { |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
50 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
51 goto done; |
2436
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
52 } |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
53 |
501 | 54 rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); |
55 if (rb == NULL) { | |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
56 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
57 goto done; |
479 | 58 } |
59 | |
60 /* | |
61 * set by ngx_pcalloc(): | |
62 * | |
63 * rb->bufs = NULL; | |
64 * rb->buf = NULL; | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
65 * rb->free = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
66 * rb->busy = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
67 * rb->chunked = NULL; |
479 | 68 */ |
69 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
70 rb->rest = -1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
71 rb->post_handler = post_handler; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
72 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
73 r->request_body = rb; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
74 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
75 if (r->headers_in.content_length_n < 0 && !r->headers_in.chunked) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
76 post_handler(r); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
77 return NGX_OK; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
78 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
79 |
633 | 80 preread = r->header_in->last - r->header_in->pos; |
83
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
81 |
633 | 82 if (preread) { |
296
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
83 |
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
84 /* there is the pre-read part of the request body */ |
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
85 |
633 | 86 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
87 "http client request body preread %uz", preread); | |
88 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
89 out.buf = r->header_in; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
90 out.next = NULL; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
91 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
92 rc = ngx_http_request_body_filter(r, &out); |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
93 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
94 if (rc != NGX_OK) { |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
95 goto done; |
479 | 96 } |
97 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
98 r->request_length += preread - (r->header_in->last - r->header_in->pos); |
299
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
99 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
100 if (!r->headers_in.chunked |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
101 && rb->rest > 0 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
102 && rb->rest <= (off_t) (r->header_in->end - r->header_in->last)) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
103 { |
633 | 104 /* the whole request body may be placed in r->header_in */ |
105 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
106 rb->buf = r->header_in; |
633 | 107 r->read_event_handler = ngx_http_read_client_request_body_handler; |
4937
3b6594a2b79f
Request body: block write events while reading body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4936
diff
changeset
|
108 r->write_event_handler = ngx_http_request_empty_handler; |
633 | 109 |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
110 rc = ngx_http_do_read_client_request_body(r); |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
111 goto done; |
633 | 112 } |
113 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
114 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
115 /* set rb->rest */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
116 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
117 if (ngx_http_request_body_filter(r, NULL) != NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
118 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
119 goto done; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
120 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
121 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
122 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
123 if (rb->rest == 0) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
124 /* the whole request body was pre-read */ |
633 | 125 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
126 if (r->request_body_in_file_only) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
127 if (ngx_http_write_request_body(r) != NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
128 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
129 goto done; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
130 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
131 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
132 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
133 post_handler(r); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
134 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
135 return NGX_OK; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
136 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
137 |
4936
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
138 if (rb->rest < 0) { |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
139 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
140 "negative request body rest"); |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
141 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
142 goto done; |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
143 } |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
144 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
145 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
146 |
633 | 147 size = clcf->client_body_buffer_size; |
148 size += size >> 2; | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
149 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
150 /* TODO: honor r->request_body_in_single_buf */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
151 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
152 if (!r->headers_in.chunked && rb->rest < size) { |
663 | 153 size = (ssize_t) rb->rest; |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
154 |
633 | 155 if (r->request_body_in_single_buf) { |
156 size += preread; | |
157 } | |
158 | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
159 } else { |
303
00c5660d2707
nginx-0.0.3-2004-04-01-20:20:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
299
diff
changeset
|
160 size = clcf->client_body_buffer_size; |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
161 } |
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
162 |
501 | 163 rb->buf = ngx_create_temp_buf(r->pool, size); |
164 if (rb->buf == NULL) { | |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
165 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
166 goto done; |
479 | 167 } |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
168 |
509 | 169 r->read_event_handler = ngx_http_read_client_request_body_handler; |
4937
3b6594a2b79f
Request body: block write events while reading body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4936
diff
changeset
|
170 r->write_event_handler = ngx_http_request_empty_handler; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
171 |
4923
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
172 rc = ngx_http_do_read_client_request_body(r); |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
173 |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
174 done: |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
175 |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
176 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
177 r->main->count--; |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
178 } |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
179 |
57174af2e695
Request body: fixed socket leak on errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4922
diff
changeset
|
180 return rc; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
181 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
182 |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
183 |
501 | 184 static void |
509 | 185 ngx_http_read_client_request_body_handler(ngx_http_request_t *r) |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
186 { |
509 | 187 ngx_int_t rc; |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
188 |
509 | 189 if (r->connection->read->timedout) { |
577 | 190 r->connection->timedout = 1; |
1075
4d203f76b757
undo "client_body_in_file_only any"
Igor Sysoev <igor@sysoev.ru>
parents:
1072
diff
changeset
|
191 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); |
299
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
192 return; |
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
193 } |
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
194 |
509 | 195 rc = ngx_http_do_read_client_request_body(r); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
196 |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
197 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
1075
4d203f76b757
undo "client_body_in_file_only any"
Igor Sysoev <igor@sysoev.ru>
parents:
1072
diff
changeset
|
198 ngx_http_finalize_request(r, rc); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
199 } |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
200 } |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
201 |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
202 |
501 | 203 static ngx_int_t |
509 | 204 ngx_http_do_read_client_request_body(ngx_http_request_t *r) |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
205 { |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
206 off_t rest; |
290
87e73f067470
nginx-0.0.2-2004-03-16-10:10:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
171
diff
changeset
|
207 size_t size; |
87e73f067470
nginx-0.0.2-2004-03-16-10:10:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
171
diff
changeset
|
208 ssize_t n; |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
209 ngx_int_t rc; |
343
6bdf858bff8c
nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents:
303
diff
changeset
|
210 ngx_buf_t *b; |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
211 ngx_chain_t *cl, out; |
509 | 212 ngx_connection_t *c; |
479 | 213 ngx_http_request_body_t *rb; |
162
96993d4d5067
nginx-0.0.1-2003-10-28-00:01:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
160
diff
changeset
|
214 ngx_http_core_loc_conf_t *clcf; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
215 |
509 | 216 c = r->connection; |
479 | 217 rb = r->request_body; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
218 |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
219 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
220 "http read client request body"); |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
221 |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
222 for ( ;; ) { |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
223 for ( ;; ) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
224 if (rb->buf->last == rb->buf->end) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
225 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
226 /* pass buffer to request body filter chain */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
227 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
228 out.buf = rb->buf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
229 out.next = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
230 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
231 rc = ngx_http_request_body_filter(r, &out); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
232 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
233 if (rc != NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
234 return rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
235 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
236 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
237 /* write to file */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
238 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
239 if (ngx_http_write_request_body(r) != NGX_OK) { |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
240 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
241 } |
479 | 242 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
243 /* update chains */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
244 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
245 rc = ngx_http_request_body_filter(r, NULL); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
246 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
247 if (rc != NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
248 return rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
249 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
250 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
251 if (rb->busy != NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
252 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
253 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
254 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
255 rb->buf->pos = rb->buf->start; |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
256 rb->buf->last = rb->buf->start; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
257 } |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
258 |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
259 size = rb->buf->end - rb->buf->last; |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
260 rest = rb->rest - (rb->buf->last - rb->buf->pos); |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
261 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
262 if ((off_t) size > rest) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
263 size = (size_t) rest; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
264 } |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
265 |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
266 n = c->recv(c, rb->buf->last, size); |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
267 |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
268 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
269 "http client request body recv %z", n); |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
270 |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
271 if (n == NGX_AGAIN) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
272 break; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
273 } |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
274 |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
275 if (n == 0) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
276 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
4593
834049edae24
Fixed grammar in error messages.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
277 "client prematurely closed connection"); |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
278 } |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
279 |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
280 if (n == 0 || n == NGX_ERROR) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
281 c->error = 1; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
282 return NGX_HTTP_BAD_REQUEST; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
283 } |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
284 |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
285 rb->buf->last += n; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
286 r->request_length += n; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
287 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
288 if (n == rest) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
289 /* pass buffer to request body filter chain */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
290 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
291 out.buf = rb->buf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
292 out.next = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
293 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
294 rc = ngx_http_request_body_filter(r, &out); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
295 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
296 if (rc != NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
297 return rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
298 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
299 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
300 |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
301 if (rb->rest == 0) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
302 break; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
303 } |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
304 |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
305 if (rb->buf->last < rb->buf->end) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
306 break; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
307 } |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
308 } |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
309 |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
310 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1112 | 311 "http client request body rest %O", rb->rest); |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
312 |
479 | 313 if (rb->rest == 0) { |
294
5cfd65b8b0a7
nginx-0.0.3-2004-03-23-09:01:52 import
Igor Sysoev <igor@sysoev.ru>
parents:
293
diff
changeset
|
314 break; |
5cfd65b8b0a7
nginx-0.0.3-2004-03-23-09:01:52 import
Igor Sysoev <igor@sysoev.ru>
parents:
293
diff
changeset
|
315 } |
5cfd65b8b0a7
nginx-0.0.3-2004-03-23-09:01:52 import
Igor Sysoev <igor@sysoev.ru>
parents:
293
diff
changeset
|
316 |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
317 if (!c->read->ready) { |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
318 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
319 ngx_add_timer(c->read, clcf->client_body_timeout); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
320 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2233
diff
changeset
|
321 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
322 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
323 } |
573 | 324 |
841
790ed4eb762e
fix big client body receiving with deferred accept()
Igor Sysoev <igor@sysoev.ru>
parents:
725
diff
changeset
|
325 return NGX_AGAIN; |
573 | 326 } |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
327 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
328 |
573 | 329 if (c->read->timer_set) { |
330 ngx_del_timer(c->read); | |
331 } | |
332 | |
633 | 333 if (rb->temp_file || r->request_body_in_file_only) { |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
334 |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
335 /* save the last part */ |
479 | 336 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
337 if (ngx_http_write_request_body(r) != NGX_OK) { |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
338 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
162
96993d4d5067
nginx-0.0.1-2003-10-28-00:01:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
160
diff
changeset
|
339 } |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
340 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
341 cl = ngx_chain_get_free_buf(r->pool, &rb->free); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
342 if (cl == NULL) { |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
343 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
344 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
345 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
346 b = cl->buf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
347 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
348 ngx_memzero(b, sizeof(ngx_buf_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
349 |
343
6bdf858bff8c
nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents:
303
diff
changeset
|
350 b->in_file = 1; |
479 | 351 b->file_last = rb->temp_file->file.offset; |
352 b->file = &rb->temp_file->file; | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
353 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
354 rb->bufs = cl; |
633 | 355 } |
356 | |
4072
cf334deeea66
Bugfix: read event was not blocked after reading body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4006
diff
changeset
|
357 r->read_event_handler = ngx_http_block_reading; |
cf334deeea66
Bugfix: read event was not blocked after reading body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4006
diff
changeset
|
358 |
479 | 359 rb->post_handler(r); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
360 |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
361 return NGX_OK; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
362 } |
633 | 363 |
364 | |
365 static ngx_int_t | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
366 ngx_http_write_request_body(ngx_http_request_t *r) |
633 | 367 { |
368 ssize_t n; | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
369 ngx_chain_t *cl; |
633 | 370 ngx_temp_file_t *tf; |
371 ngx_http_request_body_t *rb; | |
372 ngx_http_core_loc_conf_t *clcf; | |
373 | |
374 rb = r->request_body; | |
375 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
376 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
377 "http write client request body, bufs %p", rb->bufs); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
378 |
633 | 379 if (rb->temp_file == NULL) { |
380 tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); | |
381 if (tf == NULL) { | |
382 return NGX_ERROR; | |
383 } | |
384 | |
385 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
386 | |
387 tf->file.fd = NGX_INVALID_FILE; | |
388 tf->file.log = r->connection->log; | |
389 tf->path = clcf->client_body_temp_path; | |
390 tf->pool = r->pool; | |
391 tf->warn = "a client request body is buffered to a temporary file"; | |
637 | 392 tf->log_level = r->request_body_file_log_level; |
633 | 393 tf->persistent = r->request_body_in_persistent_file; |
1075
4d203f76b757
undo "client_body_in_file_only any"
Igor Sysoev <igor@sysoev.ru>
parents:
1072
diff
changeset
|
394 tf->clean = r->request_body_in_clean_file; |
633 | 395 |
396 if (r->request_body_file_group_access) { | |
1046 | 397 tf->access = 0660; |
633 | 398 } |
399 | |
400 rb->temp_file = tf; | |
4922
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
401 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
402 if (rb->bufs == NULL) { |
4922
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
403 /* empty body with r->request_body_in_file_only */ |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
404 |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
405 if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
406 tf->persistent, tf->clean, tf->access) |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
407 != NGX_OK) |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
408 { |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
409 return NGX_ERROR; |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
410 } |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
411 |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
412 return NGX_OK; |
dfa586842962
Request body: code duplication reduced, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4593
diff
changeset
|
413 } |
633 | 414 } |
415 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
416 if (rb->bufs == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
417 return NGX_OK; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
418 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
419 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
420 n = ngx_write_chain_to_temp_file(rb->temp_file, rb->bufs); |
633 | 421 |
422 /* TODO: n == 0 or not complete and level event */ | |
423 | |
424 if (n == NGX_ERROR) { | |
425 return NGX_ERROR; | |
426 } | |
427 | |
428 rb->temp_file->offset += n; | |
429 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
430 /* mark all buffers as written */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
431 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
432 for (cl = rb->bufs; cl; cl = cl->next) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
433 cl->buf->pos = cl->buf->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
434 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
435 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
436 rb->bufs = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
437 |
633 | 438 return NGX_OK; |
439 } | |
440 | |
441 | |
442 ngx_int_t | |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1369
diff
changeset
|
443 ngx_http_discard_request_body(ngx_http_request_t *r) |
633 | 444 { |
445 ssize_t size; | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
446 ngx_int_t rc; |
633 | 447 ngx_event_t *rev; |
448 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
449 if (r != r->main || r->discard_body || r->request_body) { |
633 | 450 return NGX_OK; |
451 } | |
452 | |
2436
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
453 if (ngx_http_test_expect(r) != NGX_OK) { |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
454 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
455 } |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
456 |
633 | 457 rev = r->connection->read; |
458 | |
459 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body"); | |
460 | |
461 if (rev->timer_set) { | |
462 ngx_del_timer(rev); | |
463 } | |
464 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
465 if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { |
633 | 466 return NGX_OK; |
467 } | |
468 | |
469 size = r->header_in->last - r->header_in->pos; | |
470 | |
4934
b61edaa04342
Request body: fixed discard of chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4931
diff
changeset
|
471 if (size || r->headers_in.chunked) { |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
472 rc = ngx_http_discard_request_body_filter(r, r->header_in); |
633 | 473 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
474 if (rc != NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
475 return rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
476 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
477 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
478 if (r->headers_in.content_length_n == 0) { |
633 | 479 return NGX_OK; |
480 } | |
481 } | |
482 | |
4935
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
483 rc = ngx_http_read_discarded_request_body(r); |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
484 |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
485 if (rc == NGX_OK) { |
4924
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
486 r->lingering_close = 0; |
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
487 return NGX_OK; |
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
488 } |
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
489 |
4935
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
490 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
491 return rc; |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
492 } |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
493 |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
494 /* rc == NGX_AGAIN */ |
4924
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
495 |
3214
798a7f1d3b2f
restore discard body handler after ngx_http_set_writer() set it to
Igor Sysoev <igor@sysoev.ru>
parents:
3213
diff
changeset
|
496 r->read_event_handler = ngx_http_discarded_request_body_handler; |
633 | 497 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2233
diff
changeset
|
498 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
633 | 499 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
500 } | |
501 | |
4924
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
502 r->count++; |
caca5603bded
Request body: properly handle events while discarding body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4923
diff
changeset
|
503 r->discard_body = 1; |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
504 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
505 return NGX_OK; |
633 | 506 } |
507 | |
508 | |
3214
798a7f1d3b2f
restore discard body handler after ngx_http_set_writer() set it to
Igor Sysoev <igor@sysoev.ru>
parents:
3213
diff
changeset
|
509 void |
798a7f1d3b2f
restore discard body handler after ngx_http_set_writer() set it to
Igor Sysoev <igor@sysoev.ru>
parents:
3213
diff
changeset
|
510 ngx_http_discarded_request_body_handler(ngx_http_request_t *r) |
633 | 511 { |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
512 ngx_int_t rc; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
513 ngx_msec_t timer; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
514 ngx_event_t *rev; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
515 ngx_connection_t *c; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
516 ngx_http_core_loc_conf_t *clcf; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
517 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
518 c = r->connection; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
519 rev = c->read; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
520 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
521 if (rev->timedout) { |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
522 c->timedout = 1; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
523 c->error = 1; |
3213
7fc06314c684
fix ngx_http_finalize_request() code after a body has been discarded
Igor Sysoev <igor@sysoev.ru>
parents:
3212
diff
changeset
|
524 ngx_http_finalize_request(r, NGX_ERROR); |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
525 return; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
526 } |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
527 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
528 if (r->lingering_time) { |
1640 | 529 timer = (ngx_msec_t) (r->lingering_time - ngx_time()); |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
530 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
531 if (timer <= 0) { |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
532 r->discard_body = 0; |
3181
36f6407817dc
clear r->lingering_close to disable preventively calling
Igor Sysoev <igor@sysoev.ru>
parents:
3179
diff
changeset
|
533 r->lingering_close = 0; |
3213
7fc06314c684
fix ngx_http_finalize_request() code after a body has been discarded
Igor Sysoev <igor@sysoev.ru>
parents:
3212
diff
changeset
|
534 ngx_http_finalize_request(r, NGX_ERROR); |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
535 return; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
536 } |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
537 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
538 } else { |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
539 timer = 0; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
540 } |
633 | 541 |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1369
diff
changeset
|
542 rc = ngx_http_read_discarded_request_body(r); |
633 | 543 |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
544 if (rc == NGX_OK) { |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
545 r->discard_body = 0; |
3181
36f6407817dc
clear r->lingering_close to disable preventively calling
Igor Sysoev <igor@sysoev.ru>
parents:
3179
diff
changeset
|
546 r->lingering_close = 0; |
3213
7fc06314c684
fix ngx_http_finalize_request() code after a body has been discarded
Igor Sysoev <igor@sysoev.ru>
parents:
3212
diff
changeset
|
547 ngx_http_finalize_request(r, NGX_DONE); |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
548 return; |
633 | 549 } |
550 | |
4935
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
551 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
552 c->error = 1; |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
553 ngx_http_finalize_request(r, NGX_ERROR); |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
554 return; |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
555 } |
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
556 |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
557 /* rc == NGX_AGAIN */ |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
558 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2233
diff
changeset
|
559 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1456 | 560 c->error = 1; |
3213
7fc06314c684
fix ngx_http_finalize_request() code after a body has been discarded
Igor Sysoev <igor@sysoev.ru>
parents:
3212
diff
changeset
|
561 ngx_http_finalize_request(r, NGX_ERROR); |
1373
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
562 return; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
563 } |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
564 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
565 if (timer) { |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
566 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
567 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
568 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
569 timer *= 1000; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
570 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
571 if (timer > clcf->lingering_timeout) { |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
572 timer = clcf->lingering_timeout; |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
573 } |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
574 |
fdea12ffb24a
discard request body before going to keep-alive state and use lingering timeouts
Igor Sysoev <igor@sysoev.ru>
parents:
1370
diff
changeset
|
575 ngx_add_timer(rev, timer); |
633 | 576 } |
577 } | |
578 | |
579 | |
580 static ngx_int_t | |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1369
diff
changeset
|
581 ngx_http_read_discarded_request_body(ngx_http_request_t *r) |
633 | 582 { |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
583 size_t size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
584 ssize_t n; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
585 ngx_int_t rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
586 ngx_buf_t b; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
587 u_char buffer[NGX_HTTP_DISCARD_BUFFER_SIZE]; |
633 | 588 |
589 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
590 "http read discarded body"); | |
591 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
592 ngx_memzero(&b, sizeof(ngx_buf_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
593 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
594 b.temporary = 1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
595 |
3162 | 596 for ( ;; ) { |
1367
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
597 if (r->headers_in.content_length_n == 0) { |
1369
6254b90eea4b
block reading for level events
Igor Sysoev <igor@sysoev.ru>
parents:
1367
diff
changeset
|
598 r->read_event_handler = ngx_http_block_reading; |
1367
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
599 return NGX_OK; |
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
600 } |
633 | 601 |
3162 | 602 if (!r->connection->read->ready) { |
603 return NGX_AGAIN; | |
604 } | |
605 | |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
606 size = (size_t) ngx_min(r->headers_in.content_length_n, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
607 NGX_HTTP_DISCARD_BUFFER_SIZE); |
633 | 608 |
1367
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
609 n = r->connection->recv(r->connection, buffer, size); |
633 | 610 |
1367
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
611 if (n == NGX_ERROR) { |
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
612 r->connection->error = 1; |
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
613 return NGX_OK; |
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
614 } |
633 | 615 |
1367
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
616 if (n == NGX_AGAIN) { |
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
617 return NGX_AGAIN; |
aa700583b57d
discard request body in cycle
Igor Sysoev <igor@sysoev.ru>
parents:
1290
diff
changeset
|
618 } |
633 | 619 |
1422
65dd057f71c7
cancel discarding body on EOF
Igor Sysoev <igor@sysoev.ru>
parents:
1373
diff
changeset
|
620 if (n == 0) { |
65dd057f71c7
cancel discarding body on EOF
Igor Sysoev <igor@sysoev.ru>
parents:
1373
diff
changeset
|
621 return NGX_OK; |
65dd057f71c7
cancel discarding body on EOF
Igor Sysoev <igor@sysoev.ru>
parents:
1373
diff
changeset
|
622 } |
65dd057f71c7
cancel discarding body on EOF
Igor Sysoev <igor@sysoev.ru>
parents:
1373
diff
changeset
|
623 |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
624 b.pos = buffer; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
625 b.last = buffer + n; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
626 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
627 rc = ngx_http_discard_request_body_filter(r, &b); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
628 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
629 if (rc != NGX_OK) { |
4935
7bd1c839af3b
Request body: improved handling of incorrect chunked request body.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4934
diff
changeset
|
630 return rc; |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
631 } |
3162 | 632 } |
633 | 633 } |
2436
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
634 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
635 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
636 static ngx_int_t |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
637 ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
638 { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
639 size_t size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
640 ngx_int_t rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
641 ngx_http_request_body_t *rb; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
642 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
643 if (r->headers_in.chunked) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
644 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
645 rb = r->request_body; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
646 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
647 if (rb == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
648 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
649 rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
650 if (rb == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
651 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
652 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
653 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
654 rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t)); |
4936
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
655 if (rb->chunked == NULL) { |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
656 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
657 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
658 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
659 r->request_body = rb; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
660 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
661 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
662 for ( ;; ) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
663 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
664 rc = ngx_http_parse_chunked(r, b, rb->chunked); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
665 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
666 if (rc == NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
667 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
668 /* a chunk has been parsed successfully */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
669 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
670 size = b->last - b->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
671 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
672 if ((off_t) size > rb->chunked->size) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
673 b->pos += rb->chunked->size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
674 rb->chunked->size = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
675 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
676 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
677 rb->chunked->size -= size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
678 b->pos = b->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
679 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
680 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
681 continue; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
682 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
683 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
684 if (rc == NGX_DONE) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
685 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
686 /* a whole response has been parsed successfully */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
687 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
688 r->headers_in.content_length_n = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
689 break; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
690 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
691 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
692 if (rc == NGX_AGAIN) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
693 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
694 /* set amount of data we want to see next time */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
695 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
696 r->headers_in.content_length_n = rb->chunked->length; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
697 break; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
698 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
699 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
700 /* invalid */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
701 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
702 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
703 "client sent invalid chunked body"); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
704 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
705 return NGX_HTTP_BAD_REQUEST; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
706 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
707 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
708 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
709 size = b->last - b->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
710 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
711 if ((off_t) size > r->headers_in.content_length_n) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
712 b->pos += r->headers_in.content_length_n; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
713 r->headers_in.content_length_n = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
714 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
715 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
716 b->pos = b->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
717 r->headers_in.content_length_n -= size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
718 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
719 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
720 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
721 return NGX_OK; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
722 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
723 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
724 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
725 static ngx_int_t |
2436
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
726 ngx_http_test_expect(ngx_http_request_t *r) |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
727 { |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
728 ngx_int_t n; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
729 ngx_str_t *expect; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
730 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
731 if (r->expect_tested |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
732 || r->headers_in.expect == NULL |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
733 || r->http_version < NGX_HTTP_VERSION_11) |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
734 { |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
735 return NGX_OK; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
736 } |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
737 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
738 r->expect_tested = 1; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
739 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
740 expect = &r->headers_in.expect->value; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
741 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
742 if (expect->len != sizeof("100-continue") - 1 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
743 || ngx_strncasecmp(expect->data, (u_char *) "100-continue", |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
744 sizeof("100-continue") - 1) |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
745 != 0) |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
746 { |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
747 return NGX_OK; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
748 } |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
749 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
750 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
751 "send 100 Continue"); |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
752 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
753 n = r->connection->send(r->connection, |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
754 (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF, |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
755 sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1); |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
756 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
757 if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) { |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
758 return NGX_OK; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
759 } |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
760 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
761 /* we assume that such small packet should be send successfully */ |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
762 |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
763 return NGX_ERROR; |
26d9d4a41e91
send "100 Continue" just before reading request body
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
764 } |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
765 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
766 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
767 static ngx_int_t |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
768 ngx_http_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
769 { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
770 if (r->headers_in.chunked) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
771 return ngx_http_request_body_chunked_filter(r, in); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
772 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
773 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
774 return ngx_http_request_body_length_filter(r, in); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
775 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
776 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
777 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
778 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
779 static ngx_int_t |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
780 ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
781 { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
782 size_t size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
783 ngx_int_t rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
784 ngx_buf_t *b; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
785 ngx_chain_t *cl, *tl, *out, **ll; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
786 ngx_http_request_body_t *rb; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
787 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
788 rb = r->request_body; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
789 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
790 if (rb->rest == -1) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
791 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
792 "http request body content length filter"); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
793 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
794 rb->rest = r->headers_in.content_length_n; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
795 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
796 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
797 out = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
798 ll = &out; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
799 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
800 for (cl = in; cl; cl = cl->next) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
801 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
802 tl = ngx_chain_get_free_buf(r->pool, &rb->free); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
803 if (tl == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
804 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
805 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
806 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
807 b = tl->buf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
808 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
809 ngx_memzero(b, sizeof(ngx_buf_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
810 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
811 b->temporary = 1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
812 b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
813 b->start = cl->buf->start; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
814 b->pos = cl->buf->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
815 b->last = cl->buf->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
816 b->end = cl->buf->end; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
817 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
818 size = cl->buf->last - cl->buf->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
819 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
820 if ((off_t) size < rb->rest) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
821 cl->buf->pos = cl->buf->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
822 rb->rest -= size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
823 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
824 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
825 cl->buf->pos += rb->rest; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
826 rb->rest = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
827 b->last = cl->buf->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
828 b->last_buf = 1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
829 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
830 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
831 *ll = tl; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
832 ll = &tl->next; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
833 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
834 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
835 rc = ngx_http_request_body_save_filter(r, out); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
836 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
837 ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
838 (ngx_buf_tag_t) &ngx_http_read_client_request_body); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
839 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
840 return rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
841 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
842 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
843 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
844 static ngx_int_t |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
845 ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
846 { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
847 size_t size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
848 ngx_int_t rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
849 ngx_buf_t *b; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
850 ngx_chain_t *cl, *out, *tl, **ll; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
851 ngx_http_request_body_t *rb; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
852 ngx_http_core_loc_conf_t *clcf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
853 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
854 rb = r->request_body; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
855 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
856 if (rb->rest == -1) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
857 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
858 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
859 "http request body chunked filter"); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
860 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
861 rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
862 if (rb->chunked == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
863 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
864 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
865 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
866 r->headers_in.content_length_n = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
867 rb->rest = 3; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
868 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
869 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
870 out = NULL; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
871 ll = &out; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
872 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
873 for (cl = in; cl; cl = cl->next) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
874 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
875 for ( ;; ) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
876 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
877 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
878 "http body chunked buf " |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
879 "t:%d f:%d %p, pos %p, size: %z file: %O, size: %z", |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
880 cl->buf->temporary, cl->buf->in_file, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
881 cl->buf->start, cl->buf->pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
882 cl->buf->last - cl->buf->pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
883 cl->buf->file_pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
884 cl->buf->file_last - cl->buf->file_pos); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
885 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
886 rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
887 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
888 if (rc == NGX_OK) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
889 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
890 /* a chunk has been parsed successfully */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
891 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
892 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
893 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
894 if (clcf->client_max_body_size |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
895 && clcf->client_max_body_size |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
896 < r->headers_in.content_length_n + rb->chunked->size) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
897 { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
898 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
899 "client intended to send too large chunked " |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
900 "body: %O bytes", |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
901 r->headers_in.content_length_n |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
902 + rb->chunked->size); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
903 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
904 r->lingering_close = 1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
905 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
906 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
907 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
908 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
909 tl = ngx_chain_get_free_buf(r->pool, &rb->free); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
910 if (tl == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
911 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
912 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
913 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
914 b = tl->buf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
915 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
916 ngx_memzero(b, sizeof(ngx_buf_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
917 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
918 b->temporary = 1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
919 b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
920 b->start = cl->buf->start; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
921 b->pos = cl->buf->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
922 b->last = cl->buf->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
923 b->end = cl->buf->end; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
924 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
925 *ll = tl; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
926 ll = &tl->next; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
927 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
928 size = cl->buf->last - cl->buf->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
929 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
930 if ((off_t) size > rb->chunked->size) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
931 cl->buf->pos += rb->chunked->size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
932 r->headers_in.content_length_n += rb->chunked->size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
933 rb->chunked->size = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
934 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
935 } else { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
936 rb->chunked->size -= size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
937 r->headers_in.content_length_n += size; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
938 cl->buf->pos = cl->buf->last; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
939 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
940 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
941 b->last = cl->buf->pos; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
942 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
943 continue; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
944 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
945 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
946 if (rc == NGX_DONE) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
947 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
948 /* a whole response has been parsed successfully */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
949 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
950 rb->rest = 0; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
951 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
952 tl = ngx_chain_get_free_buf(r->pool, &rb->free); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
953 if (tl == NULL) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
954 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
955 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
956 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
957 b = tl->buf; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
958 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
959 ngx_memzero(b, sizeof(ngx_buf_t)); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
960 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
961 b->last_buf = 1; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
962 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
963 *ll = tl; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
964 ll = &tl->next; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
965 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
966 break; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
967 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
968 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
969 if (rc == NGX_AGAIN) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
970 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
971 /* set rb->rest, amount of data we want to see next time */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
972 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
973 rb->rest = rb->chunked->length; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
974 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
975 break; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
976 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
977 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
978 /* invalid */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
979 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
980 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
981 "client sent invalid chunked body"); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
982 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
983 return NGX_HTTP_BAD_REQUEST; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
984 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
985 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
986 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
987 rc = ngx_http_request_body_save_filter(r, out); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
988 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
989 ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
990 (ngx_buf_tag_t) &ngx_http_read_client_request_body); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
991 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
992 return rc; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
993 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
994 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
995 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
996 static ngx_int_t |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
997 ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
998 { |
4931
190fce68b6b5
Request body: unbreak build without debug.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4930
diff
changeset
|
999 #if (NGX_DEBUG) |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1000 ngx_chain_t *cl; |
4931
190fce68b6b5
Request body: unbreak build without debug.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4930
diff
changeset
|
1001 #endif |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1002 ngx_http_request_body_t *rb; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1003 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1004 rb = r->request_body; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1005 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1006 #if (NGX_DEBUG) |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1007 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1008 for (cl = rb->bufs; cl; cl = cl->next) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1009 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1010 "http body old buf t:%d f:%d %p, pos %p, size: %z " |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1011 "file: %O, size: %z", |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1012 cl->buf->temporary, cl->buf->in_file, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1013 cl->buf->start, cl->buf->pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1014 cl->buf->last - cl->buf->pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1015 cl->buf->file_pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1016 cl->buf->file_last - cl->buf->file_pos); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1017 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1018 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1019 for (cl = in; cl; cl = cl->next) { |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1020 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1021 "http body new buf t:%d f:%d %p, pos %p, size: %z " |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1022 "file: %O, size: %z", |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1023 cl->buf->temporary, cl->buf->in_file, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1024 cl->buf->start, cl->buf->pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1025 cl->buf->last - cl->buf->pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1026 cl->buf->file_pos, |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1027 cl->buf->file_last - cl->buf->file_pos); |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1028 } |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1029 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1030 #endif |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1031 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1032 /* TODO: coalesce neighbouring buffers */ |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1033 |
4936
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
1034 if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) { |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
1035 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
240e3fb392c9
Request body: error checking fixes, negative rb->rest handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4935
diff
changeset
|
1036 } |
4930
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1037 |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1038 return NGX_OK; |
6f085bfcdb4d
Request body: chunked transfer encoding support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4924
diff
changeset
|
1039 } |