Mercurial > hg > nginx
comparison src/event/ngx_event_pipe.c @ 483:621229427cba release-0.1.16
nginx-0.1.16-RELEASE import
*) Bugfix: if the response were transferred by chunks, then on the HEAD
request the final chunk was issued.
*) Bugfix: the "Connection: keep-alive" header were issued, even if the
keepalive_timeout directive forbade the keep-alive use.
*) Bugfix: the errors in the ngx_http_fastcgi_module caused the
segmentation faults.
*) Bugfix: the compressed response encrypted by SSL may not transferred
complete.
*) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK
options, are not used for the unix domain sockets.
*) Feature: the rewrite directive supports the arguments rewriting.
*) Bugfix: the response code 400 was returned for the POST request with
the "Content-Length: 0" header; the bug had appeared in 0.1.14.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 25 Jan 2005 12:27:35 +0000 |
parents | c52408583801 |
children | d4ea69372b94 |
comparison
equal
deleted
inserted
replaced
482:49f5aef41157 | 483:621229427cba |
---|---|
15 | 15 |
16 static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p); | 16 static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p); |
17 static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); | 17 static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); |
18 static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, | 18 static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, |
19 ngx_buf_t *buf); | 19 ngx_buf_t *buf); |
20 static ngx_inline void ngx_event_pipe_add_free_buf(ngx_chain_t **chain, | |
21 ngx_chain_t *cl); | |
22 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p); | 20 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p); |
23 | 21 |
24 | 22 |
25 ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, int do_write) | 23 ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, int do_write) |
26 { | 24 { |
27 u_int flags; | 25 u_int flags; |
28 ngx_event_t *rev, *wev; | 26 ngx_event_t *rev, *wev; |
29 | 27 |
30 for ( ;; ) { | 28 for ( ;; ) { |
31 if (do_write) { | 29 if (do_write) { |
30 p->log->action = "sending to client"; | |
31 | |
32 if (ngx_event_pipe_write_to_downstream(p) == NGX_ABORT) { | 32 if (ngx_event_pipe_write_to_downstream(p) == NGX_ABORT) { |
33 return NGX_ABORT; | 33 return NGX_ABORT; |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 p->read = 0; | 37 p->read = 0; |
38 p->upstream_blocked = 0; | 38 p->upstream_blocked = 0; |
39 | |
40 p->log->action = "reading upstream"; | |
39 | 41 |
40 if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) { | 42 if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) { |
41 return NGX_ABORT; | 43 return NGX_ABORT; |
42 } | 44 } |
43 | 45 |
75 | 77 |
76 return NGX_OK; | 78 return NGX_OK; |
77 } | 79 } |
78 | 80 |
79 | 81 |
80 ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) | 82 static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) |
81 { | 83 { |
82 ssize_t n, size; | 84 ssize_t n, size; |
83 ngx_int_t rc; | 85 ngx_int_t rc; |
84 ngx_buf_t *b; | 86 ngx_buf_t *b; |
85 ngx_chain_t *chain, *cl, *tl; | 87 ngx_chain_t *chain, *cl; |
86 | 88 |
87 if (p->upstream_eof || p->upstream_error || p->upstream_done) { | 89 if (p->upstream_eof || p->upstream_error || p->upstream_done) { |
88 return NGX_OK; | 90 return NGX_OK; |
89 } | 91 } |
90 | 92 |
167 return NGX_ABORT; | 169 return NGX_ABORT; |
168 } | 170 } |
169 | 171 |
170 p->allocated++; | 172 p->allocated++; |
171 | 173 |
172 ngx_alloc_link_and_set_buf(tl, b, p->pool, NGX_ABORT); | 174 if (!(chain = ngx_alloc_chain_link(p->pool))) { |
173 chain = tl; | 175 return NGX_ABORT; |
176 } | |
177 | |
178 chain->buf = b; | |
179 chain->next = NULL; | |
174 | 180 |
175 } else if (!p->cachable && p->downstream->write->ready) { | 181 } else if (!p->cachable && p->downstream->write->ready) { |
176 | 182 |
177 /* | 183 /* |
178 * if the bufs are not needed to be saved in a cache and | 184 * if the bufs are not needed to be saved in a cache and |
189 } else if (p->cachable | 195 } else if (p->cachable |
190 || p->temp_file->offset < p->max_temp_file_size) | 196 || p->temp_file->offset < p->max_temp_file_size) |
191 { | 197 { |
192 | 198 |
193 /* | 199 /* |
194 * if it's allowed then save some bufs from r->in | 200 * if it is allowed, then save some bufs from r->in |
195 * to a temporary file, and add them to a r->out chain | 201 * to a temporary file, and add them to a r->out chain |
196 */ | 202 */ |
197 | 203 |
198 rc = ngx_event_pipe_write_chain_to_temp_file(p); | 204 rc = ngx_event_pipe_write_chain_to_temp_file(p); |
199 | 205 |
225 p->free_raw_bufs = NULL; | 231 p->free_raw_bufs = NULL; |
226 } | 232 } |
227 | 233 |
228 } else { | 234 } else { |
229 | 235 |
230 /* if there're no bufs to read in then disable a level event */ | 236 /* there are no bufs to read in */ |
231 | 237 |
232 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, | 238 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, |
233 "no pipe bufs to read in"); | 239 "no pipe bufs to read in"); |
234 | 240 |
235 break; | 241 break; |
296 p->free_raw_bufs = cl; | 302 p->free_raw_bufs = cl; |
297 } | 303 } |
298 | 304 |
299 #if (NGX_DEBUG) | 305 #if (NGX_DEBUG) |
300 | 306 |
301 if (p->in || p->busy || p->free_raw_bufs) { | |
302 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe buf"); | |
303 } | |
304 | |
305 for (cl = p->busy; cl; cl = cl->next) { | 307 for (cl = p->busy; cl; cl = cl->next) { |
306 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, | 308 ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, |
307 "pipe buf busy %p, pos %p, size: %z", | 309 "pipe buf busy s:%d t:%d f:%d " |
310 "%p, pos %p, size: %z " | |
311 "file: %O, size: %z", | |
312 (cl->buf->shadow ? 1 : 0), | |
313 cl->buf->temporary, cl->buf->in_file, | |
308 cl->buf->start, cl->buf->pos, | 314 cl->buf->start, cl->buf->pos, |
309 cl->buf->last - cl->buf->pos); | 315 cl->buf->last - cl->buf->pos, |
316 cl->buf->file_pos, | |
317 cl->buf->file_last - cl->buf->file_pos); | |
310 } | 318 } |
311 | 319 |
312 for (cl = p->out; cl; cl = cl->next) { | 320 for (cl = p->out; cl; cl = cl->next) { |
313 if (cl->buf->in_file && cl->buf->temporary) { | 321 ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, |
314 ngx_log_debug5(NGX_LOG_DEBUG_EVENT, p->log, 0, | 322 "pipe buf out s:%d t:%d f:%d " |
315 "pipe buf out shadow %p, pos %p, size: %z " | 323 "%p, pos %p, size: %z " |
316 "file: %O, size: %z", | 324 "file: %O, size: %z", |
317 cl->buf->start, cl->buf->pos, | 325 (cl->buf->shadow ? 1 : 0), |
318 cl->buf->last - cl->buf->pos, | 326 cl->buf->temporary, cl->buf->in_file, |
319 cl->buf->file_pos, | 327 cl->buf->start, cl->buf->pos, |
320 cl->buf->file_last - cl->buf->file_pos); | 328 cl->buf->last - cl->buf->pos, |
321 | 329 cl->buf->file_pos, |
322 } else if (cl->buf->in_file) { | 330 cl->buf->file_last - cl->buf->file_pos); |
323 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, | |
324 "pipe buf out file %O, size: %z", | |
325 cl->buf->file_pos, | |
326 cl->buf->file_last - cl->buf->file_pos); | |
327 } else { | |
328 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, | |
329 "pipe buf out %p, pos %p, size: %z", | |
330 cl->buf->start, cl->buf->pos, | |
331 cl->buf->last - cl->buf->pos); | |
332 } | |
333 } | 331 } |
334 | 332 |
335 for (cl = p->in; cl; cl = cl->next) { | 333 for (cl = p->in; cl; cl = cl->next) { |
336 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, | 334 ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, |
337 "pipe buf in %p, pos %p, size: %z", | 335 "pipe buf in s:%d t:%d f:%d " |
336 "%p, pos %p, size: %z " | |
337 "file: %O, size: %z", | |
338 (cl->buf->shadow ? 1 : 0), | |
339 cl->buf->temporary, cl->buf->in_file, | |
338 cl->buf->start, cl->buf->pos, | 340 cl->buf->start, cl->buf->pos, |
339 cl->buf->last - cl->buf->pos); | 341 cl->buf->last - cl->buf->pos, |
342 cl->buf->file_pos, | |
343 cl->buf->file_last - cl->buf->file_pos); | |
340 } | 344 } |
341 | 345 |
342 for (cl = p->free_raw_bufs; cl; cl = cl->next) { | 346 for (cl = p->free_raw_bufs; cl; cl = cl->next) { |
343 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, | 347 ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, |
344 "pipe buf free %p, last %p, size: %z", | 348 "pipe buf free s:%d t:%d f:%d " |
345 cl->buf->start, cl->buf->last, | 349 "%p, pos %p, size: %z " |
346 cl->buf->end - cl->buf->last); | 350 "file: %O, size: %z", |
351 (cl->buf->shadow ? 1 : 0), | |
352 cl->buf->temporary, cl->buf->in_file, | |
353 cl->buf->start, cl->buf->pos, | |
354 cl->buf->last - cl->buf->pos, | |
355 cl->buf->file_pos, | |
356 cl->buf->file_last - cl->buf->file_pos); | |
347 } | 357 } |
348 | 358 |
349 #endif | 359 #endif |
350 | 360 |
351 if ((p->upstream_eof || p->upstream_error) && p->free_raw_bufs) { | 361 if ((p->upstream_eof || p->upstream_error) && p->free_raw_bufs) { |
375 | 385 |
376 return NGX_OK; | 386 return NGX_OK; |
377 } | 387 } |
378 | 388 |
379 | 389 |
380 ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) | 390 static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) |
381 { | 391 { |
382 size_t bsize; | 392 size_t bsize; |
383 ngx_uint_t flush; | 393 ngx_uint_t flush; |
384 ngx_buf_t *b; | 394 ngx_chain_t *out, **ll, *cl; |
385 ngx_chain_t *out, **ll, *cl, *tl; | |
386 | 395 |
387 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, | 396 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, |
388 "pipe write downstream: %d", p->downstream->write->ready); | 397 "pipe write downstream: %d", p->downstream->write->ready); |
389 | 398 |
390 for ( ;; ) { | 399 for ( ;; ) { |
520 /* TODO: free buf if p->free_bufs && upstream done */ | 529 /* TODO: free buf if p->free_bufs && upstream done */ |
521 | 530 |
522 /* add the free shadow raw buf to p->free_raw_bufs */ | 531 /* add the free shadow raw buf to p->free_raw_bufs */ |
523 | 532 |
524 if (cl->buf->last_shadow) { | 533 if (cl->buf->last_shadow) { |
525 b = cl->buf->shadow; | 534 if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) { |
526 b->pos = b->last = b->start; | 535 return NGX_ABORT; |
527 b->shadow = NULL; | 536 } |
528 ngx_alloc_link_and_set_buf(tl, b, p->pool, NGX_ABORT); | |
529 ngx_event_pipe_add_free_buf(&p->free_raw_bufs, tl); | |
530 | 537 |
531 cl->buf->last_shadow = 0; | 538 cl->buf->last_shadow = 0; |
532 } | 539 } |
533 | 540 |
534 cl->buf->shadow = NULL; | 541 cl->buf->shadow = NULL; |
629 b->temp_file = 1; | 636 b->temp_file = 1; |
630 | 637 |
631 ngx_chain_add_link(p->out, p->last_out, cl); | 638 ngx_chain_add_link(p->out, p->last_out, cl); |
632 | 639 |
633 if (b->last_shadow) { | 640 if (b->last_shadow) { |
641 | |
642 if (!(tl = ngx_alloc_chain_link(p->pool))) { | |
643 return NGX_ABORT; | |
644 } | |
645 | |
646 tl->buf = b->shadow; | |
647 tl->next = NULL; | |
648 | |
649 *last_free = tl; | |
650 last_free = &tl->next; | |
651 | |
634 b->shadow->pos = b->shadow->start; | 652 b->shadow->pos = b->shadow->start; |
635 b->shadow->last = b->shadow->start; | 653 b->shadow->last = b->shadow->start; |
636 | 654 |
637 ngx_alloc_link_and_set_buf(tl, b->shadow, p->pool, NGX_ABORT); | 655 ngx_event_pipe_remove_shadow_links(b->shadow); |
638 | |
639 *last_free = tl; | |
640 last_free = &tl->next; | |
641 } | 656 } |
642 } | 657 } |
643 | 658 |
644 return NGX_OK; | 659 return NGX_OK; |
645 } | 660 } |
671 b->tag = p->tag; | 686 b->tag = p->tag; |
672 b->last_shadow = 1; | 687 b->last_shadow = 1; |
673 b->recycled = 1; | 688 b->recycled = 1; |
674 buf->shadow = b; | 689 buf->shadow = b; |
675 | 690 |
676 ngx_alloc_link_and_set_buf(cl, b, p->pool, NGX_ERROR); | 691 if (!(cl = ngx_alloc_chain_link(p->pool))) { |
692 return NGX_ERROR; | |
693 } | |
694 | |
695 cl->buf = b; | |
696 cl->next = NULL; | |
677 | 697 |
678 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); | 698 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); |
679 | 699 |
680 ngx_chain_add_link(p->in, p->last_in, cl); | 700 ngx_chain_add_link(p->in, p->last_in, cl); |
681 | 701 |
740 ll = &cl->next; | 760 ll = &cl->next; |
741 } | 761 } |
742 } | 762 } |
743 | 763 |
744 | 764 |
745 static ngx_inline void ngx_event_pipe_add_free_buf(ngx_chain_t **chain, | 765 ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b) |
746 ngx_chain_t *cl) | |
747 { | 766 { |
748 if (*chain == NULL) { | 767 ngx_chain_t *cl; |
749 *chain = cl; | 768 |
750 return; | 769 if (!(cl = ngx_alloc_chain_link(p->pool))) { |
751 } | 770 return NGX_ERROR; |
752 | 771 } |
753 if ((*chain)->buf->pos != (*chain)->buf->last) { | 772 |
754 cl->next = (*chain)->next; | 773 b->pos = b->start; |
755 (*chain)->next = cl; | 774 b->last = b->start; |
756 | 775 b->shadow = NULL; |
757 } else { | 776 |
758 cl->next = (*chain); | 777 cl->buf = b; |
759 (*chain) = cl; | 778 |
760 } | 779 if (p->free_raw_bufs == NULL) { |
780 p->free_raw_bufs = cl; | |
781 cl->next = NULL; | |
782 | |
783 return NGX_OK; | |
784 } | |
785 | |
786 if (p->free_raw_bufs->buf->pos == p->free_raw_bufs->buf->last) { | |
787 | |
788 /* add the free buf to the list start */ | |
789 | |
790 cl->next = p->free_raw_bufs; | |
791 p->free_raw_bufs = cl; | |
792 | |
793 return NGX_OK; | |
794 } | |
795 | |
796 /* the first free buf is partialy filled, thus add the free buf after it */ | |
797 | |
798 cl->next = p->free_raw_bufs->next; | |
799 p->free_raw_bufs->next = cl; | |
800 | |
801 return NGX_OK; | |
761 } | 802 } |
762 | 803 |
763 | 804 |
764 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p) | 805 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p) |
765 { | 806 { |
766 ngx_buf_t *b; | |
767 ngx_chain_t *cl, *tl; | 807 ngx_chain_t *cl, *tl; |
768 | 808 |
769 for ( ;; ) { | 809 for ( ;; ) { |
770 if (p->busy) { | 810 if (p->busy) { |
771 cl = p->busy; | 811 cl = p->busy; |
783 return NGX_OK; | 823 return NGX_OK; |
784 } | 824 } |
785 | 825 |
786 while (cl) { | 826 while (cl) { |
787 if (cl->buf->last_shadow) { | 827 if (cl->buf->last_shadow) { |
788 b = cl->buf->shadow; | 828 if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) { |
789 b->pos = b->last = b->start; | |
790 b->shadow = NULL; | |
791 | |
792 if (!(tl = ngx_alloc_chain_link(p->pool))) { | |
793 return NGX_ABORT; | 829 return NGX_ABORT; |
794 } | 830 } |
795 | |
796 tl->buf = b; | |
797 tl->next = NULL; | |
798 | |
799 ngx_event_pipe_add_free_buf(&p->free_raw_bufs, tl); | |
800 | 831 |
801 cl->buf->last_shadow = 0; | 832 cl->buf->last_shadow = 0; |
802 } | 833 } |
803 | 834 |
804 cl->buf->shadow = NULL; | 835 cl->buf->shadow = NULL; |