Mercurial > hg > nginx-vendor-0-6
comparison src/http/ngx_http_request_body.c @ 28:7ca9bdc82b3f NGINX_0_1_14
nginx 0.1.14
*) Feature: the autoconfiguration directives:
--http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and
--http-fastcgi-temp-path=PATH
*) Change: the directory name for the temporary files with the client
request body is specified by directive client_body_temp_path, by
default it is <prefix>/client_body_temp.
*) Feature: the ngx_http_fastcgi_module and the directives:
fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params,
fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout,
fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers,
fastcgi_busy_buffers_size, fastcgi_temp_path,
fastcgi_max_temp_file_size, fastcgi_temp_file_write_size,
fastcgi_next_upstream, and fastcgi_x_powered_by.
*) Bugfix: the "[alert] zero size buf" error; bug appeared in 0.1.3.
*) Change: the URI must be specified after the host name in the
proxy_pass directive.
*) Change: the %3F symbol in the URI was considered as the argument
string start.
*) Feature: the unix domain sockets support in the
ngx_http_proxy_module.
*) Feature: the ssl_engine and ssl_ciphers directives.
Thanks to Sergey Skvortsov for SSL-accelerator.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 18 Jan 2005 00:00:00 +0300 |
parents | 420dd3f9e703 |
children | 72eb30262aac |
comparison
equal
deleted
inserted
replaced
27:66901c2556fd | 28:7ca9bdc82b3f |
---|---|
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | 11 |
12 | 12 |
13 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev); | 13 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev); |
14 static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r); | 14 static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r, |
15 | 15 ngx_connection_t *c); |
16 | 16 |
17 ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r) | 17 /* |
18 * on completion ngx_http_read_client_request_body() adds to | |
19 * r->request_body->bufs one or two bufs: | |
20 * *) one memory buf that was preread in r->header_in; | |
21 * *) one memory or file buf that contains the rest of the body | |
22 */ | |
23 | |
24 ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r, | |
25 ngx_http_client_body_handler_pt post_handler) | |
26 | |
18 { | 27 { |
19 ssize_t size; | 28 ssize_t size; |
20 ngx_buf_t *b; | 29 ngx_buf_t *b; |
21 ngx_chain_t *cl; | 30 ngx_chain_t *cl; |
31 ngx_http_request_body_t *rb; | |
22 ngx_http_core_loc_conf_t *clcf; | 32 ngx_http_core_loc_conf_t *clcf; |
23 | 33 |
34 if (!(rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)))) { | |
35 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
36 } | |
37 | |
38 r->request_body = rb; | |
39 | |
40 if (r->headers_in.content_length_n <= 0) { | |
41 post_handler(r); | |
42 return NGX_OK; | |
43 } | |
44 | |
45 rb->post_handler = post_handler; | |
46 | |
47 /* | |
48 * set by ngx_pcalloc(): | |
49 * | |
50 * rb->bufs = NULL; | |
51 * rb->buf = NULL; | |
52 * rb->rest = 0; | |
53 */ | |
54 | |
24 size = r->header_in->last - r->header_in->pos; | 55 size = r->header_in->last - r->header_in->pos; |
25 | 56 |
26 if (size) { | 57 if (size) { |
27 | 58 |
28 /* there is the pre-read part of the request body */ | 59 /* there is the pre-read part of the request body */ |
29 | 60 |
30 ngx_test_null(b, ngx_calloc_buf(r->pool), | 61 if (!(b = ngx_calloc_buf(r->pool))) { |
31 NGX_HTTP_INTERNAL_SERVER_ERROR); | 62 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
63 } | |
32 | 64 |
33 b->temporary = 1; | 65 b->temporary = 1; |
34 b->start = b->pos = r->header_in->pos; | 66 b->start = b->pos = r->header_in->pos; |
35 b->end = b->last = r->header_in->last; | 67 b->end = b->last = r->header_in->last; |
36 | 68 |
37 ngx_alloc_link_and_set_buf(r->request_body->bufs, b, r->pool, | 69 if (!(rb->bufs = ngx_alloc_chain_link(r->pool))) { |
38 NGX_HTTP_INTERNAL_SERVER_ERROR); | 70 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
71 } | |
72 | |
73 rb->bufs->buf = b; | |
74 rb->bufs->next = NULL; | |
39 | 75 |
40 if (size >= r->headers_in.content_length_n) { | 76 if (size >= r->headers_in.content_length_n) { |
41 | 77 |
42 /* the whole request body was pre-read */ | 78 /* the whole request body was pre-read */ |
43 | 79 |
44 r->header_in->pos += r->headers_in.content_length_n; | 80 r->header_in->pos += r->headers_in.content_length_n; |
45 r->request_length += r->headers_in.content_length_n; | 81 r->request_length += r->headers_in.content_length_n; |
46 | 82 |
47 r->request_body->handler(r->request_body->data); | 83 post_handler(r); |
48 | 84 |
49 return NGX_OK; | 85 return NGX_OK; |
50 } | 86 } |
51 | 87 |
52 r->header_in->pos = r->header_in->last; | 88 r->header_in->pos = r->header_in->last; |
54 } | 90 } |
55 | 91 |
56 | 92 |
57 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 93 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
58 | 94 |
59 r->request_body->rest = r->headers_in.content_length_n - size; | 95 rb->rest = r->headers_in.content_length_n - size; |
60 | 96 |
61 if (r->request_body->rest | 97 if (rb->rest < clcf->client_body_buffer_size |
62 < clcf->client_body_buffer_size | |
63 + (clcf->client_body_buffer_size >> 2)) | 98 + (clcf->client_body_buffer_size >> 2)) |
64 { | 99 { |
65 size = r->request_body->rest; | 100 size = rb->rest; |
66 | 101 |
67 } else { | 102 } else { |
68 size = clcf->client_body_buffer_size; | 103 size = clcf->client_body_buffer_size; |
69 } | 104 } |
70 | 105 |
71 ngx_test_null(r->request_body->buf, ngx_create_temp_buf(r->pool, size), | 106 if (!(rb->buf = ngx_create_temp_buf(r->pool, size))) { |
72 NGX_HTTP_INTERNAL_SERVER_ERROR); | 107 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
73 | 108 } |
74 ngx_alloc_link_and_set_buf(cl, r->request_body->buf, r->pool, | 109 |
75 NGX_HTTP_INTERNAL_SERVER_ERROR); | 110 if (!(cl = ngx_alloc_chain_link(r->pool))) { |
76 | 111 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
77 if (r->request_body->bufs) { | 112 } |
78 r->request_body->bufs->next = cl; | 113 |
114 cl->buf = rb->buf; | |
115 cl->next = NULL; | |
116 | |
117 if (rb->bufs) { | |
118 rb->bufs->next = cl; | |
79 | 119 |
80 } else { | 120 } else { |
81 r->request_body->bufs = cl; | 121 rb->bufs = cl; |
82 } | 122 } |
83 | 123 |
84 r->connection->read->event_handler = | 124 r->connection->read->event_handler = |
85 ngx_http_read_client_request_body_handler; | 125 ngx_http_read_client_request_body_handler; |
86 | 126 |
87 return ngx_http_do_read_client_request_body(r); | 127 return ngx_http_do_read_client_request_body(r, r->connection); |
88 } | 128 } |
89 | 129 |
90 | 130 |
91 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev) | 131 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev) |
92 { | 132 { |
100 if (rev->timedout) { | 140 if (rev->timedout) { |
101 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); | 141 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); |
102 return; | 142 return; |
103 } | 143 } |
104 | 144 |
105 rc = ngx_http_do_read_client_request_body(r); | 145 rc = ngx_http_do_read_client_request_body(r, c); |
106 | 146 |
107 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 147 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
108 ngx_http_finalize_request(r, rc); | 148 ngx_http_finalize_request(r, rc); |
109 } | 149 } |
110 } | 150 } |
111 | 151 |
112 | 152 |
113 static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r) | 153 static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r, |
154 ngx_connection_t *c) | |
114 { | 155 { |
115 size_t size; | 156 size_t size; |
116 ssize_t n; | 157 ssize_t n; |
117 ngx_buf_t *b; | 158 ngx_buf_t *b; |
118 ngx_connection_t *c; | 159 ngx_temp_file_t *tf; |
160 ngx_http_request_body_t *rb; | |
119 ngx_http_core_loc_conf_t *clcf; | 161 ngx_http_core_loc_conf_t *clcf; |
120 | 162 |
121 c = r->connection; | 163 rb = r->request_body; |
122 | 164 |
123 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 165 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
124 "http read client request body"); | 166 "http read client request body"); |
125 | 167 |
126 for ( ;; ) { | 168 for ( ;; ) { |
127 if (r->request_body->buf->last == r->request_body->buf->end) { | 169 if (rb->buf->last == rb->buf->end) { |
128 n = ngx_write_chain_to_temp_file(r->request_body->temp_file, | 170 |
129 r->request_body->bufs->next ? r->request_body->bufs->next: | 171 if (rb->temp_file == NULL) { |
130 r->request_body->bufs); | 172 if (!(tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)))) { |
173 return NGX_ERROR; | |
174 } | |
175 | |
176 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
177 | |
178 tf->file.fd = NGX_INVALID_FILE; | |
179 tf->file.log = r->connection->log; | |
180 tf->path = clcf->client_body_temp_path; | |
181 tf->pool = r->pool; | |
182 tf->warn = "a client request body is buffered " | |
183 "to a temporary file"; | |
184 | |
185 rb->temp_file = tf; | |
186 | |
187 } | |
188 | |
189 n = ngx_write_chain_to_temp_file(rb->temp_file, | |
190 rb->bufs->next ? rb->bufs->next: | |
191 rb->bufs); | |
131 | 192 |
132 /* TODO: n == 0 or not complete and level event */ | 193 /* TODO: n == 0 or not complete and level event */ |
133 | 194 |
134 if (n == NGX_ERROR) { | 195 if (n == NGX_ERROR) { |
135 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 196 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
136 } | 197 } |
137 | 198 |
138 r->request_body->temp_file->offset += n; | 199 rb->temp_file->offset += n; |
139 | 200 |
140 r->request_body->buf->pos = r->request_body->buf->start; | 201 rb->buf->pos = rb->buf->start; |
141 r->request_body->buf->last = r->request_body->buf->start; | 202 rb->buf->last = rb->buf->start; |
142 } | 203 } |
143 | 204 |
144 size = r->request_body->buf->end - r->request_body->buf->last; | 205 size = rb->buf->end - rb->buf->last; |
145 | 206 |
146 if (size > r->request_body->rest) { | 207 if (size > rb->rest) { |
147 size = r->request_body->rest; | 208 size = rb->rest; |
148 } | 209 } |
149 | 210 |
150 n = c->recv(c, r->request_body->buf->last, size); | 211 n = c->recv(c, rb->buf->last, size); |
151 | 212 |
152 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 213 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
153 "http client request body recv %z", n); | 214 "http client request body recv %z", n); |
154 | 215 |
155 if (n == NGX_AGAIN) { | 216 if (n == NGX_AGAIN) { |
171 if (n == 0 || n == NGX_ERROR) { | 232 if (n == 0 || n == NGX_ERROR) { |
172 r->closed = 1; | 233 r->closed = 1; |
173 return NGX_HTTP_BAD_REQUEST; | 234 return NGX_HTTP_BAD_REQUEST; |
174 } | 235 } |
175 | 236 |
176 r->request_body->buf->last += n; | 237 rb->buf->last += n; |
177 r->request_body->rest -= n; | 238 rb->rest -= n; |
178 r->request_length += n; | 239 r->request_length += n; |
179 | 240 |
180 if (r->request_body->rest == 0) { | 241 if (rb->rest == 0) { |
181 break; | 242 break; |
182 } | 243 } |
183 | 244 |
184 if (r->request_body->buf->last < r->request_body->buf->end) { | 245 if (rb->buf->last < rb->buf->end) { |
185 break; | 246 break; |
186 } | 247 } |
187 } | 248 } |
188 | 249 |
189 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 250 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
190 "http client request body rest %uz", | 251 "http client request body rest %uz", rb->rest); |
191 r->request_body->rest); | 252 |
192 | 253 if (rb->rest) { |
193 if (r->request_body->rest) { | |
194 return NGX_AGAIN; | 254 return NGX_AGAIN; |
195 } | 255 } |
196 | 256 |
197 if (r->request_body->temp_file->file.fd != NGX_INVALID_FILE) { | 257 if (rb->temp_file) { |
198 | 258 |
199 /* save the last part */ | 259 /* save the last part */ |
200 n = ngx_write_chain_to_temp_file(r->request_body->temp_file, | 260 |
201 r->request_body->bufs->next ? r->request_body->bufs->next: | 261 n = ngx_write_chain_to_temp_file(rb->temp_file, |
202 r->request_body->bufs); | 262 rb->bufs->next ? rb->bufs->next: |
263 rb->bufs); | |
203 | 264 |
204 /* TODO: n == 0 or not complete and level event */ | 265 /* TODO: n == 0 or not complete and level event */ |
205 | 266 |
206 if (n == NGX_ERROR) { | 267 if (n == NGX_ERROR) { |
207 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 268 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
211 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 272 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
212 } | 273 } |
213 | 274 |
214 b->in_file = 1; | 275 b->in_file = 1; |
215 b->file_pos = 0; | 276 b->file_pos = 0; |
216 b->file_last = r->request_body->temp_file->file.offset; | 277 b->file_last = rb->temp_file->file.offset; |
217 b->file = &r->request_body->temp_file->file; | 278 b->file = &rb->temp_file->file; |
218 | 279 |
219 if (r->request_body->bufs->next) { | 280 if (rb->bufs->next) { |
220 r->request_body->bufs->next->buf = b; | 281 rb->bufs->next->buf = b; |
221 | 282 |
222 } else { | 283 } else { |
223 r->request_body->bufs->buf = b; | 284 rb->bufs->buf = b; |
224 } | 285 } |
225 } | 286 } |
226 | 287 |
227 r->request_body->handler(r->request_body->data); | 288 rb->post_handler(r); |
228 | 289 |
229 return NGX_OK; | 290 return NGX_OK; |
230 } | 291 } |