| 611 | } |
| 612 | |
| 613 | static ssize_t stream_request_data(nghttp2_session *ngh2, int32_t stream_id, |
| 614 | uint8_t *buf, size_t length, |
| 615 | uint32_t *data_flags, |
| 616 | nghttp2_data_source *source, void *user_data) |
| 617 | { |
| 618 | h2_proxy_stream *stream; |
| 619 | apr_status_t status = APR_SUCCESS; |
| 620 | |
| 621 | *data_flags = 0; |
| 622 | stream = nghttp2_session_get_stream_user_data(ngh2, stream_id); |
| 623 | if (!stream) { |
| 624 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03361) |
| 625 | "h2_proxy_stream(NULL): data_read, stream %d not found", |
| 626 | stream_id); |
| 627 | return NGHTTP2_ERR_CALLBACK_FAILURE; |
| 628 | } |
| 629 | |
| 630 | if (stream->session->ping_state != H2_PING_ST_NONE) { |
| 631 | /* suspend until we hear from the other side */ |
| 632 | stream->waiting_on_ping = 1; |
| 633 | status = APR_EAGAIN; |
| 634 | } |
| 635 | else if (stream->r->expecting_100) { |
| 636 | /* suspend until the answer comes */ |
| 637 | stream->waiting_on_100 = 1; |
| 638 | status = APR_EAGAIN; |
| 639 | } |
| 640 | else if (APR_BRIGADE_EMPTY(stream->input)) { |
| 641 | status = ap_get_brigade(stream->r->input_filters, stream->input, |
| 642 | AP_MODE_READBYTES, APR_NONBLOCK_READ, |
| 643 | H2MAX(APR_BUCKET_BUFF_SIZE, length)); |
| 644 | ap_log_rerror(APLOG_MARK, APLOG_TRACE2, status, stream->r, |
| 645 | "h2_proxy_stream(%s-%d): request body read", |
| 646 | stream->session->id, stream->id); |
| 647 | } |
| 648 | |
| 649 | if (status == APR_SUCCESS) { |
| 650 | size_t readlen = 0; |
| 651 | while (status == APR_SUCCESS |
| 652 | && (readlen < length) |
| 653 | && !APR_BRIGADE_EMPTY(stream->input)) { |
| 654 | apr_bucket* b = APR_BRIGADE_FIRST(stream->input); |
| 655 | if (APR_BUCKET_IS_METADATA(b)) { |
| 656 | if (APR_BUCKET_IS_EOS(b)) { |
| 657 | *data_flags |= NGHTTP2_DATA_FLAG_EOF; |
| 658 | } |
| 659 | else { |
| 660 | /* we do nothing more regarding any meta here */ |
| 661 | } |
| 662 | } |
| 663 | else { |
| 664 | const char *bdata = NULL; |
| 665 | apr_size_t blen = 0; |
| 666 | status = apr_bucket_read(b, &bdata, &blen, APR_BLOCK_READ); |
| 667 | |
| 668 | if (status == APR_SUCCESS && blen > 0) { |
| 669 | size_t copylen = H2MIN(length - readlen, blen); |
| 670 | memcpy(buf, bdata, copylen); |
nothing calls this directly
no test coverage detected