Mercurial > hg > nginx-vendor-0-8
comparison src/core/ngx_output_chain.c @ 18:6f8b0dc0f8dd NGINX_0_1_9
nginx 0.1.9
*) Bugfix: the proxied request was sent without arguments if the
request contains "//", "/./", "/../" or "%XX".
*) Bugfix: the large compressed responses may be transferred not
completely.
*) Bugfix: the files bigger than 2G was not transferred on Linux that
does not support sendfile64().
*) Bugfix: while the build configuration on Linux the
--with-poll_module parameter was required; bug appeared in 0.1.8.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 25 Nov 2004 00:00:00 +0300 |
parents | 74b1868dd3cd |
children | 8b6db3bda591 |
comparison
equal
deleted
inserted
replaced
17:9acb68bb0698 | 18:6f8b0dc0f8dd |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 | 10 |
11 | 11 |
12 #define NGX_NONE 1 | 12 #if 0 |
13 #define NGX_SENDFILE_LIMIT 4096 | |
14 #endif | |
15 | |
16 | |
17 #define NGX_NONE 1 | |
13 | 18 |
14 | 19 |
15 static ngx_inline ngx_int_t | 20 static ngx_inline ngx_int_t |
16 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf); | 21 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf); |
22 static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool, | |
23 ngx_chain_t **chain, ngx_chain_t *in); | |
17 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, | 24 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, |
18 ngx_uint_t sendfile); | 25 ngx_uint_t sendfile); |
19 | 26 |
20 | 27 |
21 ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in) | 28 ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in) |
24 size_t size, bsize; | 31 size_t size, bsize; |
25 ngx_chain_t *cl, *out, **last_out; | 32 ngx_chain_t *cl, *out, **last_out; |
26 | 33 |
27 if (ctx->in == NULL && ctx->busy == NULL) { | 34 if (ctx->in == NULL && ctx->busy == NULL) { |
28 | 35 |
29 /* | 36 /* |
30 * the short path for the case when the ctx->in and ctx->busy chains | 37 * the short path for the case when the ctx->in and ctx->busy chains |
31 * are empty, the incoming chain is empty too or has the single buf | 38 * are empty, the incoming chain is empty too or has the single buf |
32 * that does not require the copy | 39 * that does not require the copy |
33 */ | 40 */ |
34 | 41 |
35 if (in == NULL) { | 42 if (in == NULL) { |
36 return ctx->output_filter(ctx->filter_ctx, in); | 43 return ctx->output_filter(ctx->filter_ctx, in); |
37 } | 44 } |
38 | 45 |
39 if (in->next == NULL | 46 if (in->next == NULL |
47 #if (NGX_SENDFILE_LIMIT) | |
48 && !(in->buf->in_file && in->buf->file_last > NGX_SENDFILE_LIMIT) | |
49 #endif | |
40 && (!ngx_output_chain_need_to_copy(ctx, in->buf))) | 50 && (!ngx_output_chain_need_to_copy(ctx, in->buf))) |
41 { | 51 { |
42 return ctx->output_filter(ctx->filter_ctx, in); | 52 return ctx->output_filter(ctx->filter_ctx, in); |
43 } | 53 } |
44 } | 54 } |
45 | 55 |
46 /* add the incoming buf to the chain ctx->in */ | 56 /* add the incoming buf to the chain ctx->in */ |
47 | 57 |
48 if (in) { | 58 if (in) { |
49 if (ngx_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) { | 59 if (ngx_output_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) { |
50 return NGX_ERROR; | 60 return NGX_ERROR; |
51 } | 61 } |
52 } | 62 } |
53 | 63 |
54 last = NGX_NONE; | 64 last = NGX_NONE; |
189 | 199 |
190 | 200 |
191 static ngx_inline ngx_int_t | 201 static ngx_inline ngx_int_t |
192 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf) | 202 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf) |
193 { | 203 { |
204 ngx_uint_t sendfile; | |
205 | |
194 if (ngx_buf_special(buf)) { | 206 if (ngx_buf_special(buf)) { |
195 return 0; | 207 return 0; |
196 } | 208 } |
197 | 209 |
198 if (!ctx->sendfile) { | 210 sendfile = ctx->sendfile; |
211 | |
212 #if (NGX_SENDFILE_LIMIT) | |
213 | |
214 if (buf->in_file && buf->file_pos >= NGX_SENDFILE_LIMIT) { | |
215 sendfile = 0; | |
216 } | |
217 | |
218 #endif | |
219 | |
220 if (!sendfile) { | |
199 | 221 |
200 if (!ngx_buf_in_memory(buf)) { | 222 if (!ngx_buf_in_memory(buf)) { |
201 return 1; | 223 return 1; |
202 } | 224 } |
203 | 225 |
211 if (ctx->need_in_temp && (buf->memory || buf->mmap)) { | 233 if (ctx->need_in_temp && (buf->memory || buf->mmap)) { |
212 return 1; | 234 return 1; |
213 } | 235 } |
214 | 236 |
215 return 0; | 237 return 0; |
238 } | |
239 | |
240 | |
241 static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool, | |
242 ngx_chain_t **chain, ngx_chain_t *in) | |
243 { | |
244 ngx_chain_t *cl, **ll; | |
245 #if (NGX_SENDFILE_LIMIT) | |
246 ngx_buf_t *b, *buf; | |
247 #endif | |
248 | |
249 ll = chain; | |
250 | |
251 for (cl = *chain; cl; cl = cl->next) { | |
252 ll = &cl->next; | |
253 } | |
254 | |
255 while (in) { | |
256 | |
257 if (!(cl = ngx_alloc_chain_link(pool))) { | |
258 return NGX_ERROR; | |
259 } | |
260 | |
261 #if (NGX_SENDFILE_LIMIT) | |
262 | |
263 buf = in->buf; | |
264 | |
265 if (buf->in_file | |
266 && buf->file_pos < NGX_SENDFILE_LIMIT | |
267 && buf->file_last > NGX_SENDFILE_LIMIT) | |
268 { | |
269 if (!(b = ngx_calloc_buf(pool))) { | |
270 return NGX_ERROR; | |
271 } | |
272 | |
273 ngx_memcpy(b, buf, sizeof(ngx_buf_t)); | |
274 | |
275 if (ngx_buf_in_memory(buf)) { | |
276 buf->pos += (ssize_t) (NGX_SENDFILE_LIMIT - buf->file_pos); | |
277 b->last = buf->pos; | |
278 } | |
279 | |
280 buf->file_pos = NGX_SENDFILE_LIMIT; | |
281 b->file_last = NGX_SENDFILE_LIMIT; | |
282 | |
283 cl->buf = b; | |
284 | |
285 } else { | |
286 cl->buf = buf; | |
287 in = in->next; | |
288 } | |
289 | |
290 #else | |
291 cl->buf = in->buf; | |
292 in = in->next; | |
293 | |
294 #endif | |
295 | |
296 *ll = cl; | |
297 ll = &cl->next; | |
298 } | |
299 | |
300 *ll = NULL; | |
301 | |
302 return NGX_OK; | |
216 } | 303 } |
217 | 304 |
218 | 305 |
219 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, | 306 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, |
220 ngx_uint_t sendfile) | 307 ngx_uint_t sendfile) |
225 size = ngx_buf_size(src); | 312 size = ngx_buf_size(src); |
226 | 313 |
227 if (size > (size_t) (dst->end - dst->pos)) { | 314 if (size > (size_t) (dst->end - dst->pos)) { |
228 size = dst->end - dst->pos; | 315 size = dst->end - dst->pos; |
229 } | 316 } |
317 | |
318 #if (NGX_SENDFILE_LIMIT) | |
319 | |
320 if (src->in_file && src->file_pos >= NGX_SENDFILE_LIMIT) { | |
321 sendfile = 0; | |
322 } | |
323 | |
324 #endif | |
230 | 325 |
231 if (ngx_buf_in_memory(src)) { | 326 if (ngx_buf_in_memory(src)) { |
232 ngx_memcpy(dst->pos, src->pos, size); | 327 ngx_memcpy(dst->pos, src->pos, size); |
233 src->pos += size; | 328 src->pos += size; |
234 dst->last += size; | 329 dst->last += size; |