diff options
author | Dash Shendy | 2011-07-08 22:55:17 +0200 |
---|---|---|
committer | Dash Shendy | 2011-07-08 22:55:17 +0200 |
commit | b4a875b12ad2ef07f38ae23b3d3e853b5a59bf89 (patch) | |
tree | c6b9c824f3b1c8d953d5bbda80008503799e4308 /src/gnutls_io.c | |
parent | b59327cde81cddced2a35742bd203c242669d6dc (diff) |
EOC Bucket Infinite Loop Bugfix
Signed-off-by: Dash Shendy <neuromancer@dash.za.net>
Diffstat (limited to 'src/gnutls_io.c')
-rw-r--r-- | src/gnutls_io.c | 85 |
1 files changed, 35 insertions, 50 deletions
diff --git a/src/gnutls_io.c b/src/gnutls_io.c index 37b73e7..4a550c3 100644 --- a/src/gnutls_io.c +++ b/src/gnutls_io.c | |||
@@ -541,7 +541,6 @@ apr_status_t mgs_filter_input(ap_filter_t * f, | |||
541 | apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) | 541 | apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) |
542 | { | 542 | { |
543 | apr_size_t ret; | 543 | apr_size_t ret; |
544 | apr_bucket *e; | ||
545 | mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx; | 544 | mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx; |
546 | apr_status_t status = APR_SUCCESS; | 545 | apr_status_t status = APR_SUCCESS; |
547 | apr_read_type_e rblock = APR_NONBLOCK_READ; | 546 | apr_read_type_e rblock = APR_NONBLOCK_READ; |
@@ -562,48 +561,32 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) | |||
562 | while (!APR_BRIGADE_EMPTY(bb)) { | 561 | while (!APR_BRIGADE_EMPTY(bb)) { |
563 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); | 562 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); |
564 | 563 | ||
565 | if (AP_BUCKET_IS_EOC(bucket)) { | 564 | if (AP_BUCKET_IS_EOS(bucket)) { |
566 | if (ctxt->session != NULL) { | 565 | return ap_pass_brigade(f->next, bb); |
567 | do { | 566 | } else if (APR_BUCKET_IS_FLUSH(bucket)) { |
568 | ret = | 567 | /* Try Flush */ |
569 | gnutls_bye(ctxt->session, | 568 | if( write_flush(ctxt) < 0) { |
570 | GNUTLS_SHUT_WR); | 569 | /* Flush Error */ |
571 | } while (ret == GNUTLS_E_INTERRUPTED | 570 | return ctxt->output_rc; |
572 | || ret == GNUTLS_E_AGAIN); | 571 | } |
573 | } | 572 | /* cleanup! */ |
574 | 573 | apr_bucket_delete(bucket); | |
575 | apr_bucket_copy(bucket, &e); | 574 | } else if (AP_BUCKET_IS_EOC(bucket)) { |
576 | APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e); | 575 | /* End Of Connection */ |
577 | 576 | if (ctxt->session != NULL) { | |
578 | if ((status = | 577 | /* Try A Clean Shutdown */ |
579 | ap_pass_brigade(f->next, | 578 | do { |
580 | ctxt->output_bb)) != | 579 | ret = gnutls_bye( ctxt->session, |
581 | APR_SUCCESS) { | 580 | GNUTLS_SHUT_WR); |
582 | apr_brigade_cleanup(ctxt->output_bb); | 581 | } while(ret == GNUTLS_E_INTERRUPTED || |
583 | return status; | 582 | ret == GNUTLS_E_AGAIN); |
584 | } | 583 | /* De-Initialize Session */ |
585 | 584 | gnutls_deinit(ctxt->session); | |
586 | apr_brigade_cleanup(ctxt->output_bb); | 585 | ctxt->session = NULL; |
587 | if (ctxt->session) { | 586 | } |
588 | gnutls_deinit(ctxt->session); | 587 | /* Pass next brigade! */ |
589 | ctxt->session = NULL; | 588 | return ap_pass_brigade(f->next, bb); |
590 | } | 589 | } else { |
591 | continue; | ||
592 | } else if (APR_BUCKET_IS_FLUSH(bucket) | ||
593 | || APR_BUCKET_IS_EOS(bucket)) { | ||
594 | |||
595 | apr_bucket_copy(bucket, &e); | ||
596 | APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e); | ||
597 | if ((status = | ||
598 | ap_pass_brigade(f->next, | ||
599 | bb)) != APR_SUCCESS) { | ||
600 | apr_brigade_cleanup(ctxt->output_bb); | ||
601 | return status; | ||
602 | } | ||
603 | |||
604 | apr_brigade_cleanup(ctxt->output_bb); | ||
605 | continue; | ||
606 | } else { | ||
607 | /* filter output */ | 590 | /* filter output */ |
608 | const char *data; | 591 | const char *data; |
609 | apr_size_t len; | 592 | apr_size_t len; |
@@ -612,15 +595,20 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) | |||
612 | apr_bucket_read(bucket, &data, &len, rblock); | 595 | apr_bucket_read(bucket, &data, &len, rblock); |
613 | 596 | ||
614 | if (APR_STATUS_IS_EAGAIN(status)) { | 597 | if (APR_STATUS_IS_EAGAIN(status)) { |
615 | rblock = APR_BLOCK_READ; | 598 | /* No data available so Flush! */ |
616 | continue; /* and try again with a blocking read. */ | 599 | if (write_flush(ctxt) < 0) { |
600 | return ctxt->output_rc; | ||
601 | } | ||
602 | /* Try again with a blocking read. */ | ||
603 | rblock = APR_BLOCK_READ; | ||
604 | continue; | ||
617 | } | 605 | } |
618 | 606 | ||
619 | rblock = APR_NONBLOCK_READ; | 607 | rblock = APR_NONBLOCK_READ; |
620 | 608 | ||
621 | if (!APR_STATUS_IS_EOF(status) | 609 | if (!APR_STATUS_IS_EOF(status) |
622 | && (status != APR_SUCCESS)) { | 610 | && (status != APR_SUCCESS)) { |
623 | break; | 611 | return status; |
624 | } | 612 | } |
625 | 613 | ||
626 | if (len > 0) { | 614 | if (len > 0) { |
@@ -651,6 +639,7 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) | |||
651 | if (ctxt->output_rc == APR_SUCCESS) { | 639 | if (ctxt->output_rc == APR_SUCCESS) { |
652 | ctxt->output_rc = | 640 | ctxt->output_rc = |
653 | APR_EGENERAL; | 641 | APR_EGENERAL; |
642 | return ctxt->output_rc; | ||
654 | } | 643 | } |
655 | } else if (ret != len) { | 644 | } else if (ret != len) { |
656 | /* Not able to send the entire bucket, | 645 | /* Not able to send the entire bucket, |
@@ -660,10 +649,6 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) | |||
660 | } | 649 | } |
661 | 650 | ||
662 | apr_bucket_delete(bucket); | 651 | apr_bucket_delete(bucket); |
663 | |||
664 | if (ctxt->output_rc != APR_SUCCESS) { | ||
665 | break; | ||
666 | } | ||
667 | } | 652 | } |
668 | } | 653 | } |
669 | 654 | ||