Mercurial > hg > nginx-quic
annotate src/http/ngx_http_request_body.c @ 667:63a820b0bc6c release-0.3.55
nginx-0.3.55-RELEASE import
*) Feature: the "stub" parameter in the "include" SSI command.
*) Feature: the "block" SSI command.
*) Feature: the unicode2nginx script was added to contrib.
*) Bugfix: if a "root" was specified by variable only, then the root
was relative to a server prefix.
*) Bugfix: if the request contained "//" or "/./" and escaped symbols
after them, then the proxied request was sent unescaped.
*) Bugfix: the $r->headers_in("Cookie") of the ngx_http_perl_module now
returns all "Cookie" header lines.
*) Bugfix: a segmentation fault occurred if
"client_body_in_file_only on" was used and nginx switched to a next
upstream.
*) Bugfix: on some condition while reconfiguration character codes
inside the "charset_map" may be treated invalid; the bug had
appeared in 0.3.50.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 28 Jul 2006 15:16:17 +0000 |
parents | 5fd7a5e99047 |
children | b80f94fa2197 |
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 |
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
|
4 */ |
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 |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
6 |
83
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
7 #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
|
8 #include <ngx_core.h> |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
9 #include <ngx_event.h> |
83
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); | |
633 | 15 static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r, |
16 ngx_chain_t *body); | |
17 static void ngx_http_finalize_request_body(ngx_http_request_t *r, ngx_int_t rc); | |
18 static void ngx_http_read_discarded_body_handler(ngx_http_request_t *r); | |
19 static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r); | |
20 | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
21 |
479 | 22 /* |
23 * on completion ngx_http_read_client_request_body() adds to | |
24 * r->request_body->bufs one or two bufs: | |
25 * *) one memory buf that was preread in r->header_in; | |
26 * *) one memory or file buf that contains the rest of the body | |
27 */ | |
83
a7e45c45a95c
nginx-0.0.1-2003-04-28-19:06:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
82
diff
changeset
|
28 |
501 | 29 ngx_int_t |
30 ngx_http_read_client_request_body(ngx_http_request_t *r, | |
31 ngx_http_client_body_handler_pt post_handler) | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
32 { |
663 | 33 size_t preread; |
34 ssize_t size; | |
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
|
35 ngx_buf_t *b; |
633 | 36 ngx_chain_t *cl, **next; |
479 | 37 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
|
38 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
|
39 |
537 | 40 if (r->request_body || r->discard_body) { |
509 | 41 post_handler(r); |
42 return NGX_OK; | |
43 } | |
44 | |
501 | 45 rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); |
46 if (rb == NULL) { | |
479 | 47 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
48 } | |
49 | |
50 r->request_body = rb; | |
51 | |
52 if (r->headers_in.content_length_n <= 0) { | |
53 post_handler(r); | |
54 return NGX_OK; | |
55 } | |
56 | |
57 rb->post_handler = post_handler; | |
58 | |
59 /* | |
60 * set by ngx_pcalloc(): | |
61 * | |
62 * rb->bufs = NULL; | |
63 * rb->buf = NULL; | |
64 * rb->rest = 0; | |
65 */ | |
66 | |
633 | 67 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
|
68 |
633 | 69 if (preread) { |
296
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
70 |
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
71 /* 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
|
72 |
633 | 73 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
74 "http client request body preread %uz", preread); | |
75 | |
501 | 76 b = ngx_calloc_buf(r->pool); |
77 if (b == NULL) { | |
479 | 78 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
79 } | |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
80 |
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
|
81 b->temporary = 1; |
633 | 82 b->start = r->header_in->pos; |
83 b->pos = r->header_in->pos; | |
84 b->last = r->header_in->last; | |
85 b->end = r->header_in->end; | |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
86 |
501 | 87 rb->bufs = ngx_alloc_chain_link(r->pool); |
88 if (rb->bufs == NULL) { | |
479 | 89 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
90 } | |
91 | |
92 rb->bufs->buf = b; | |
93 rb->bufs->next = NULL; | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
94 |
667 | 95 rb->buf = b; |
96 | |
665 | 97 if ((off_t) preread >= r->headers_in.content_length_n) { |
296
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
98 |
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
99 /* the whole request body was pre-read */ |
bfe099e3f5b4
nginx-0.0.3-2004-03-26-19:13:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
294
diff
changeset
|
100 |
663 | 101 r->header_in->pos += (size_t) r->headers_in.content_length_n; |
475 | 102 r->request_length += r->headers_in.content_length_n; |
299
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
103 |
633 | 104 if (r->request_body_in_file_only) { |
105 if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) { | |
106 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
107 } | |
108 } | |
109 | |
479 | 110 post_handler(r); |
299
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
111 |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
112 return NGX_OK; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
113 } |
162
96993d4d5067
nginx-0.0.1-2003-10-28-00:01:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
160
diff
changeset
|
114 |
633 | 115 /* |
116 * to not consider the body as pipelined request in | |
117 * ngx_http_set_keepalive() | |
118 */ | |
162
96993d4d5067
nginx-0.0.1-2003-10-28-00:01:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
160
diff
changeset
|
119 r->header_in->pos = r->header_in->last; |
633 | 120 |
121 r->request_length += preread; | |
122 | |
123 rb->rest = r->headers_in.content_length_n - preread; | |
124 | |
665 | 125 if (rb->rest <= (off_t) (b->end - b->last)) { |
633 | 126 |
127 /* the whole request body may be placed in r->header_in */ | |
128 | |
129 r->read_event_handler = ngx_http_read_client_request_body_handler; | |
130 | |
131 return ngx_http_do_read_client_request_body(r); | |
132 } | |
133 | |
134 next = &rb->bufs->next; | |
135 | |
136 } else { | |
137 b = NULL; | |
138 rb->rest = r->headers_in.content_length_n; | |
139 next = &rb->bufs; | |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
140 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
141 |
303
00c5660d2707
nginx-0.0.3-2004-04-01-20:20:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
299
diff
changeset
|
142 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
00c5660d2707
nginx-0.0.3-2004-04-01-20:20:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
299
diff
changeset
|
143 |
633 | 144 size = clcf->client_body_buffer_size; |
145 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
|
146 |
663 | 147 if (rb->rest < size) { |
148 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
|
149 |
633 | 150 if (r->request_body_in_single_buf) { |
151 size += preread; | |
152 } | |
153 | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
154 } else { |
303
00c5660d2707
nginx-0.0.3-2004-04-01-20:20:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
299
diff
changeset
|
155 size = clcf->client_body_buffer_size; |
633 | 156 |
157 /* disable copying buffer for r->request_body_in_single_buf */ | |
158 b = NULL; | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
159 } |
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
160 |
501 | 161 rb->buf = ngx_create_temp_buf(r->pool, size); |
162 if (rb->buf == NULL) { | |
479 | 163 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
164 } | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
165 |
501 | 166 cl = ngx_alloc_chain_link(r->pool); |
167 if (cl == NULL) { | |
479 | 168 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
169 } | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
170 |
479 | 171 cl->buf = rb->buf; |
172 cl->next = NULL; | |
173 | |
633 | 174 if (b && r->request_body_in_single_buf) { |
175 size = b->last - b->pos; | |
176 ngx_memcpy(rb->buf->pos, b->pos, size); | |
177 rb->buf->last += size; | |
178 | |
179 next = &rb->bufs; | |
180 } | |
181 | |
182 *next = cl; | |
183 | |
184 if (r->request_body_in_file_only || r->request_body_in_single_buf) { | |
185 rb->to_write = rb->bufs; | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
186 |
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
187 } else { |
633 | 188 rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs; |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
189 } |
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
190 |
509 | 191 r->read_event_handler = ngx_http_read_client_request_body_handler; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
192 |
509 | 193 return ngx_http_do_read_client_request_body(r); |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
194 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
195 |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
196 |
501 | 197 static void |
509 | 198 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
|
199 { |
509 | 200 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
|
201 |
509 | 202 if (r->connection->read->timedout) { |
577 | 203 r->connection->timedout = 1; |
633 | 204 ngx_http_finalize_request_body(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
|
205 return; |
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
206 } |
46b7eeb8a116
nginx-0.0.3-2004-03-30-19:59:50 import
Igor Sysoev <igor@sysoev.ru>
parents:
297
diff
changeset
|
207 |
509 | 208 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
|
209 |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
210 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
633 | 211 ngx_http_finalize_request_body(r, rc); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
212 } |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
213 } |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
214 |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
215 |
501 | 216 static ngx_int_t |
509 | 217 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
|
218 { |
290
87e73f067470
nginx-0.0.2-2004-03-16-10:10:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
171
diff
changeset
|
219 size_t size; |
87e73f067470
nginx-0.0.2-2004-03-16-10:10:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
171
diff
changeset
|
220 ssize_t n; |
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
|
221 ngx_buf_t *b; |
509 | 222 ngx_connection_t *c; |
479 | 223 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
|
224 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
|
225 |
509 | 226 c = r->connection; |
479 | 227 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
|
228 |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
229 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
|
230 "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
|
231 |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
232 for ( ;; ) { |
479 | 233 if (rb->buf->last == rb->buf->end) { |
234 | |
633 | 235 if (ngx_http_write_request_body(r, rb->to_write) != NGX_OK) { |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
236 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
237 } |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
238 |
633 | 239 rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs; |
479 | 240 rb->buf->last = rb->buf->start; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
241 } |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
242 |
479 | 243 size = rb->buf->end - rb->buf->last; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
244 |
665 | 245 if ((off_t) size > rb->rest) { |
663 | 246 size = (size_t) rb->rest; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
247 } |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
248 |
479 | 249 n = c->recv(c, rb->buf->last, size); |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
250 |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
251 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
461 | 252 "http client request body recv %z", n); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
253 |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
254 if (n == NGX_AGAIN) { |
573 | 255 break; |
162
96993d4d5067
nginx-0.0.1-2003-10-28-00:01:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
160
diff
changeset
|
256 } |
96993d4d5067
nginx-0.0.1-2003-10-28-00:01:00 import
Igor Sysoev <igor@sysoev.ru>
parents:
160
diff
changeset
|
257 |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
258 if (n == 0) { |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
259 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
260 "client closed prematurely connection"); |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
261 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
262 |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
263 if (n == 0 || n == NGX_ERROR) { |
583 | 264 c->error = 1; |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
265 return NGX_HTTP_BAD_REQUEST; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
266 } |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
267 |
479 | 268 rb->buf->last += n; |
269 rb->rest -= n; | |
475 | 270 r->request_length += n; |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
271 |
479 | 272 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
|
273 break; |
5cfd65b8b0a7
nginx-0.0.3-2004-03-23-09:01:52 import
Igor Sysoev <igor@sysoev.ru>
parents:
293
diff
changeset
|
274 } |
5cfd65b8b0a7
nginx-0.0.3-2004-03-23-09:01:52 import
Igor Sysoev <igor@sysoev.ru>
parents:
293
diff
changeset
|
275 |
479 | 276 if (rb->buf->last < rb->buf->end) { |
292
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
277 break; |
a472bfb778b3
nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
278 } |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
279 } |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
280 |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
281 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
479 | 282 "http client request body rest %uz", rb->rest); |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
283 |
479 | 284 if (rb->rest) { |
573 | 285 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
286 ngx_add_timer(c->read, clcf->client_body_timeout); | |
287 | |
288 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { | |
289 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
290 } | |
291 | |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
292 return NGX_AGAIN; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
293 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
294 |
573 | 295 if (c->read->timer_set) { |
296 ngx_del_timer(c->read); | |
297 } | |
298 | |
633 | 299 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
|
300 |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
301 /* save the last part */ |
479 | 302 |
633 | 303 if (ngx_http_write_request_body(r, rb->to_write) != NGX_OK) { |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
304 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
|
305 } |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
306 |
501 | 307 b = ngx_calloc_buf(r->pool); |
308 if (b == NULL) { | |
293
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
309 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
|
310 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
311 |
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
|
312 b->in_file = 1; |
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
|
313 b->file_pos = 0; |
479 | 314 b->file_last = rb->temp_file->file.offset; |
315 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
|
316 |
479 | 317 if (rb->bufs->next) { |
318 rb->bufs->next->buf = b; | |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
319 |
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
320 } else { |
479 | 321 rb->bufs->buf = b; |
160
e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
Igor Sysoev <igor@sysoev.ru>
parents:
83
diff
changeset
|
322 } |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
323 } |
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
324 |
633 | 325 if (r->request_body_in_file_only && rb->bufs->next) { |
326 rb->bufs = rb->bufs->next; | |
327 } | |
328 | |
479 | 329 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
|
330 |
ec3c049681fd
nginx-0.0.3-2004-03-19-08:25:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
292
diff
changeset
|
331 return NGX_OK; |
82
fccdb921e8b8
nginx-0.0.1-2003-04-25-18:43:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
332 } |
633 | 333 |
334 | |
335 static ngx_int_t | |
336 ngx_http_write_request_body(ngx_http_request_t *r, ngx_chain_t *body) | |
337 { | |
338 ssize_t n; | |
339 ngx_temp_file_t *tf; | |
340 ngx_http_request_body_t *rb; | |
341 ngx_http_core_loc_conf_t *clcf; | |
342 | |
343 rb = r->request_body; | |
344 | |
345 if (rb->temp_file == NULL) { | |
346 tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); | |
347 if (tf == NULL) { | |
348 return NGX_ERROR; | |
349 } | |
350 | |
351 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
352 | |
353 tf->file.fd = NGX_INVALID_FILE; | |
354 tf->file.log = r->connection->log; | |
355 tf->path = clcf->client_body_temp_path; | |
356 tf->pool = r->pool; | |
357 tf->warn = "a client request body is buffered to a temporary file"; | |
637 | 358 tf->log_level = r->request_body_file_log_level; |
633 | 359 tf->persistent = r->request_body_in_persistent_file; |
360 | |
361 if (r->request_body_file_group_access) { | |
362 tf->mode = 0660; | |
363 } | |
364 | |
365 rb->temp_file = tf; | |
366 } | |
367 | |
368 n = ngx_write_chain_to_temp_file(rb->temp_file, body); | |
369 | |
370 /* TODO: n == 0 or not complete and level event */ | |
371 | |
372 if (n == NGX_ERROR) { | |
373 return NGX_ERROR; | |
374 } | |
375 | |
376 rb->temp_file->offset += n; | |
377 | |
378 return NGX_OK; | |
379 } | |
380 | |
381 | |
382 static void | |
383 ngx_http_finalize_request_body(ngx_http_request_t *r, ngx_int_t rc) | |
384 { | |
385 if (r->request_body->temp_file | |
386 && r->request_body_in_persistent_file | |
387 && r->request_body_delete_incomplete_file) | |
388 { | |
389 if (ngx_delete_file(r->request_body->temp_file->file.name.data) | |
390 == NGX_FILE_ERROR) | |
391 { | |
392 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
393 ngx_delete_file_n " \"%s\" failed", | |
394 r->request_body->temp_file->file.name.data); | |
395 } | |
396 } | |
397 | |
398 ngx_http_finalize_request(r, rc); | |
399 } | |
400 | |
401 | |
402 ngx_int_t | |
403 ngx_http_discard_body(ngx_http_request_t *r) | |
404 { | |
405 ssize_t size; | |
406 ngx_event_t *rev; | |
407 | |
408 if (r != r->main) { | |
409 return NGX_OK; | |
410 } | |
411 | |
412 rev = r->connection->read; | |
413 | |
414 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body"); | |
415 | |
416 if (rev->timer_set) { | |
417 ngx_del_timer(rev); | |
418 } | |
419 | |
420 if (r->headers_in.content_length_n <= 0) { | |
421 return NGX_OK; | |
422 } | |
423 | |
424 r->discard_body = 1; | |
425 | |
426 size = r->header_in->last - r->header_in->pos; | |
427 | |
428 if (size) { | |
429 if (r->headers_in.content_length_n > size) { | |
430 r->headers_in.content_length_n -= size; | |
431 | |
432 } else { | |
663 | 433 r->header_in->pos += (size_t) r->headers_in.content_length_n; |
633 | 434 r->headers_in.content_length_n = 0; |
435 return NGX_OK; | |
436 } | |
437 } | |
438 | |
439 r->read_event_handler = ngx_http_read_discarded_body_handler; | |
440 | |
441 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { | |
442 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
443 } | |
444 | |
445 return ngx_http_read_discarded_body(r); | |
446 } | |
447 | |
448 | |
449 static void | |
450 ngx_http_read_discarded_body_handler(ngx_http_request_t *r) | |
451 { | |
452 ngx_int_t rc; | |
453 | |
454 rc = ngx_http_read_discarded_body(r); | |
455 | |
456 if (rc == NGX_AGAIN) { | |
457 if (ngx_handle_read_event(r->connection->read, 0) == NGX_ERROR) { | |
458 ngx_http_finalize_request(r, rc); | |
459 return; | |
460 } | |
461 } | |
462 | |
463 if (rc != NGX_OK) { | |
464 ngx_http_finalize_request(r, rc); | |
465 } | |
466 } | |
467 | |
468 | |
469 static ngx_int_t | |
470 ngx_http_read_discarded_body(ngx_http_request_t *r) | |
471 { | |
663 | 472 size_t size; |
473 ssize_t n; | |
633 | 474 u_char buffer[NGX_HTTP_DISCARD_BUFFER_SIZE]; |
475 | |
476 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
477 "http read discarded body"); | |
478 | |
479 if (r->headers_in.content_length_n == 0) { | |
480 return NGX_OK; | |
481 } | |
482 | |
663 | 483 size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ? |
484 NGX_HTTP_DISCARD_BUFFER_SIZE: | |
485 (size_t) r->headers_in.content_length_n; | |
633 | 486 |
487 n = r->connection->recv(r->connection, buffer, size); | |
488 | |
489 if (n == NGX_ERROR) { | |
490 | |
491 r->connection->error = 1; | |
492 | |
493 /* | |
494 * if a client request body is discarded then we already set | |
495 * some HTTP response code for client and we can ignore the error | |
496 */ | |
497 | |
498 return NGX_OK; | |
499 } | |
500 | |
501 if (n == NGX_AGAIN) { | |
502 return NGX_AGAIN; | |
503 } | |
504 | |
505 r->headers_in.content_length_n -= n; | |
506 | |
507 return NGX_OK; | |
508 } |