diff options
Diffstat (limited to 'src/gnutls_io.c')
-rw-r--r-- | src/gnutls_io.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/gnutls_io.c b/src/gnutls_io.c index ec2d08c..856b6a3 100644 --- a/src/gnutls_io.c +++ b/src/gnutls_io.c | |||
@@ -372,7 +372,7 @@ static void gnutls_do_handshake(mod_gnutls_handle_t * ctxt) | |||
372 | ctxt->status = -1; | 372 | ctxt->status = -1; |
373 | return; | 373 | return; |
374 | #else | 374 | #else |
375 | ret = gnutls_handshake(ctxt->session); | 375 | ret = gnutls_handshake(ctxt->session); |
376 | if (ret < 0) { | 376 | if (ret < 0) { |
377 | if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED | 377 | if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED |
378 | || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { | 378 | || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { |
@@ -419,7 +419,7 @@ apr_status_t mod_gnutls_filter_input(ap_filter_t * f, | |||
419 | } | 419 | } |
420 | 420 | ||
421 | if (ctxt->status < 0) { | 421 | if (ctxt->status < 0) { |
422 | // return ap_get_brigade(f->next, bb, mode, block, readbytes); | 422 | return ap_get_brigade(f->next, bb, mode, block, readbytes); |
423 | } | 423 | } |
424 | 424 | ||
425 | /* XXX: we don't currently support anything other than these modes. */ | 425 | /* XXX: we don't currently support anything other than these modes. */ |
@@ -485,22 +485,35 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
485 | 485 | ||
486 | while (!APR_BRIGADE_EMPTY(bb)) { | 486 | while (!APR_BRIGADE_EMPTY(bb)) { |
487 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); | 487 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); |
488 | if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) { | 488 | if (APR_BUCKET_IS_EOS(bucket)) { |
489 | /** TODO: GnuTLS doesn't have a special flush method? **/ | 489 | |
490 | /* gnutls_bye(ctxt->session, GNUTLS_SHUT_RDWR); */ | ||
491 | |||
492 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { | ||
493 | return status; | ||
494 | } | ||
495 | break; | ||
496 | |||
497 | } else if (APR_BUCKET_IS_FLUSH(bucket)) { | ||
498 | |||
490 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { | 499 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { |
491 | return status; | 500 | return status; |
492 | } | 501 | } |
493 | break; | 502 | break; |
503 | |||
494 | } | 504 | } |
495 | else if (AP_BUCKET_IS_EOC(bucket)) { | 505 | else if (AP_BUCKET_IS_EOC(bucket)) { |
496 | gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); | ||
497 | 506 | ||
507 | gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); | ||
508 | gnutls_deinit(ctxt->session); | ||
498 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { | 509 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { |
499 | return status; | 510 | return status; |
500 | } | 511 | } |
501 | break; | 512 | break; |
513 | |||
502 | } | 514 | } |
503 | else { | 515 | else { |
516 | |||
504 | /* filter output */ | 517 | /* filter output */ |
505 | const char *data; | 518 | const char *data; |
506 | apr_size_t len; | 519 | apr_size_t len; |
@@ -518,7 +531,10 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
518 | break; | 531 | break; |
519 | } | 532 | } |
520 | 533 | ||
521 | ret = gnutls_record_send(ctxt->session, data, len); | 534 | do { |
535 | ret = gnutls_record_send(ctxt->session, data, len); | ||
536 | } | ||
537 | while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); | ||
522 | 538 | ||
523 | if (ret < 0) { | 539 | if (ret < 0) { |
524 | /* error sending output */ | 540 | /* error sending output */ |
@@ -531,6 +547,8 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
531 | } | 547 | } |
532 | } | 548 | } |
533 | else if ((apr_size_t) ret != len) { | 549 | else if ((apr_size_t) ret != len) { |
550 | //apr_bucket_split(bucket, ret); | ||
551 | //APR_BUCKET_REMOVE(bucket); | ||
534 | /* not all of the data was sent. */ | 552 | /* not all of the data was sent. */ |
535 | /* mod_ssl basicly errors out here.. this doesn't seem right? */ | 553 | /* mod_ssl basicly errors out here.. this doesn't seem right? */ |
536 | ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->output_rc, | 554 | ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->output_rc, |
@@ -538,6 +556,7 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
538 | "GnuTLS: failed to write %" APR_SSIZE_T_FMT | 556 | "GnuTLS: failed to write %" APR_SSIZE_T_FMT |
539 | " of %" APR_SIZE_T_FMT " bytes.", | 557 | " of %" APR_SIZE_T_FMT " bytes.", |
540 | len - (apr_size_t) ret, len); | 558 | len - (apr_size_t) ret, len); |
559 | //continue; | ||
541 | if (ctxt->output_rc == APR_SUCCESS) { | 560 | if (ctxt->output_rc == APR_SUCCESS) { |
542 | ctxt->output_rc = APR_EGENERAL; | 561 | ctxt->output_rc = APR_EGENERAL; |
543 | } | 562 | } |