| 652 | #endif |
| 653 | |
| 654 | static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, |
| 655 | char *buf, |
| 656 | apr_size_t *len) |
| 657 | { |
| 658 | apr_size_t wanted = *len; |
| 659 | apr_size_t bytes = 0; |
| 660 | int rc; |
| 661 | |
| 662 | *len = 0; |
| 663 | |
| 664 | /* If we have something leftover from last time, try that first. */ |
| 665 | if ((bytes = char_buffer_read(&inctx->cbuf, buf, wanted))) { |
| 666 | *len = bytes; |
| 667 | if (inctx->mode == AP_MODE_SPECULATIVE) { |
| 668 | /* We want to rollback this read. */ |
| 669 | if (inctx->cbuf.length > 0) { |
| 670 | inctx->cbuf.value -= bytes; |
| 671 | inctx->cbuf.length += bytes; |
| 672 | } else { |
| 673 | char_buffer_write(&inctx->cbuf, buf, (int)bytes); |
| 674 | } |
| 675 | return APR_SUCCESS; |
| 676 | } |
| 677 | /* This could probably be *len == wanted, but be safe from stray |
| 678 | * photons. |
| 679 | */ |
| 680 | if (*len >= wanted) { |
| 681 | return APR_SUCCESS; |
| 682 | } |
| 683 | if (inctx->mode == AP_MODE_GETLINE) { |
| 684 | if (memchr(buf, APR_ASCII_LF, *len)) { |
| 685 | return APR_SUCCESS; |
| 686 | } |
| 687 | } |
| 688 | else { |
| 689 | /* Down to a nonblock pattern as we have some data already |
| 690 | */ |
| 691 | inctx->block = APR_NONBLOCK_READ; |
| 692 | } |
| 693 | } |
| 694 | |
| 695 | while (1) { |
| 696 | |
| 697 | if (!inctx->filter_ctx->pssl) { |
| 698 | /* Ensure a non-zero error code is returned */ |
| 699 | if (inctx->rc == APR_SUCCESS) { |
| 700 | inctx->rc = APR_EGENERAL; |
| 701 | } |
| 702 | break; |
| 703 | } |
| 704 | |
| 705 | /* We rely on SSL_get_error() after the read, which requires an empty |
| 706 | * error queue before the read in order to work properly. |
| 707 | */ |
| 708 | ERR_clear_error(); |
| 709 | |
| 710 | /* SSL_read may not read because we haven't taken enough data |
| 711 | * from the stack. This is where we want to consider all of |
no test coverage detected