| 1423 | } |
| 1424 | |
| 1425 | static ssize_t stream_data_cb(nghttp2_session *ng2s, |
| 1426 | int32_t stream_id, |
| 1427 | uint8_t *buf, |
| 1428 | size_t length, |
| 1429 | uint32_t *data_flags, |
| 1430 | nghttp2_data_source *source, |
| 1431 | void *puser) |
| 1432 | { |
| 1433 | h2_session *session = (h2_session *)puser; |
| 1434 | conn_rec *c1 = session->c1; |
| 1435 | apr_off_t buf_len; |
| 1436 | int eos, header_blocked; |
| 1437 | apr_status_t rv; |
| 1438 | h2_stream *stream; |
| 1439 | |
| 1440 | /* nghttp2 wants to send more DATA for the stream. |
| 1441 | * we should have submitted the final response at this time |
| 1442 | * after receiving output via stream_do_responses() */ |
| 1443 | ap_assert(session); |
| 1444 | (void)ng2s; |
| 1445 | (void)buf; |
| 1446 | (void)source; |
| 1447 | stream = nghttp2_session_get_stream_user_data(session->ngh2, stream_id); |
| 1448 | |
| 1449 | if (!stream) { |
| 1450 | ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c1, |
| 1451 | APLOGNO(02937) |
| 1452 | H2_SSSN_STRM_MSG(session, stream_id, "data_cb, stream not found")); |
| 1453 | return NGHTTP2_ERR_CALLBACK_FAILURE; |
| 1454 | } |
| 1455 | H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK); |
| 1456 | if (!stream->output || !stream->response || !stream->out_buffer) { |
| 1457 | return NGHTTP2_ERR_DEFERRED; |
| 1458 | } |
| 1459 | if (stream->rst_error) { |
| 1460 | return NGHTTP2_ERR_DEFERRED; |
| 1461 | } |
| 1462 | if (h2_c1_io_needs_flush(&session->io)) { |
| 1463 | rv = h2_c1_io_pass(&session->io); |
| 1464 | if (APR_STATUS_IS_EAGAIN(rv)) { |
| 1465 | ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c1, |
| 1466 | H2_SSSN_STRM_MSG(session, stream_id, "suspending on c1 out needs flush")); |
| 1467 | h2_stream_dispatch(stream, H2_SEV_OUT_C1_BLOCK); |
| 1468 | return NGHTTP2_ERR_DEFERRED; |
| 1469 | } |
| 1470 | else if (rv) { |
| 1471 | h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, rv, NULL); |
| 1472 | return NGHTTP2_ERR_CALLBACK_FAILURE; |
| 1473 | } |
| 1474 | } |
| 1475 | |
| 1476 | /* determine how much we'd like to send. We cannot send more than |
| 1477 | * is requested. But we can reduce the size in case the master |
| 1478 | * connection operates in smaller chunks. (TSL warmup) */ |
| 1479 | if (stream->session->io.write_size > 0) { |
| 1480 | apr_size_t chunk_len = stream->session->io.write_size - H2_FRAME_HDR_LEN; |
| 1481 | if (length > chunk_len) { |
| 1482 | length = chunk_len; |
nothing calls this directly
no test coverage detected