comparison src/event/ngx_event_pipe.c @ 32:da8c190bdaba NGINX_0_1_16

nginx 0.1.16 *) 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; bug appeared in 0.1.14.
author Igor Sysoev <http://sysoev.ru>
date Tue, 25 Jan 2005 00:00:00 +0300
parents 7ca9bdc82b3f
children 72eb30262aac
comparison
equal deleted inserted replaced
31:1b17dd824438 32:da8c190bdaba
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;