1 #include "quiche/http2/adapter/nghttp2_data_provider.h"
2
3 #include <memory>
4
5 #include "quiche/http2/adapter/http2_visitor_interface.h"
6 #include "quiche/http2/adapter/nghttp2_util.h"
7
8 namespace http2 {
9 namespace adapter {
10 namespace callbacks {
11
12 namespace {
13 const size_t kFrameHeaderSize = 9;
14 }
15
DataFrameSourceReadCallback(nghttp2_session *,int32_t,uint8_t *,size_t length,uint32_t * data_flags,nghttp2_data_source * source,void *)16 ssize_t DataFrameSourceReadCallback(nghttp2_session* /* session */,
17 int32_t /* stream_id */, uint8_t* /* buf */,
18 size_t length, uint32_t* data_flags,
19 nghttp2_data_source* source,
20 void* /* user_data */) {
21 *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
22 auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
23 auto [result_length, done] = frame_source->SelectPayloadLength(length);
24 if (result_length == 0 && !done) {
25 return NGHTTP2_ERR_DEFERRED;
26 } else if (result_length == DataFrameSource::kError) {
27 return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
28 }
29 if (done) {
30 *data_flags |= NGHTTP2_DATA_FLAG_EOF;
31 }
32 if (!frame_source->send_fin()) {
33 *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
34 }
35 return result_length;
36 }
37
DataFrameSourceSendCallback(nghttp2_session *,nghttp2_frame *,const uint8_t * framehd,size_t length,nghttp2_data_source * source,void *)38 int DataFrameSourceSendCallback(nghttp2_session* /* session */,
39 nghttp2_frame* /* frame */,
40 const uint8_t* framehd, size_t length,
41 nghttp2_data_source* source,
42 void* /* user_data */) {
43 auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
44 frame_source->Send(ToStringView(framehd, kFrameHeaderSize), length);
45 return 0;
46 }
47
48 } // namespace callbacks
49
MakeDataProvider(DataFrameSource * source)50 std::unique_ptr<nghttp2_data_provider> MakeDataProvider(
51 DataFrameSource* source) {
52 if (source == nullptr) {
53 return nullptr;
54 }
55 auto provider = std::make_unique<nghttp2_data_provider>();
56 provider->source.ptr = source;
57 provider->read_callback = &callbacks::DataFrameSourceReadCallback;
58 return provider;
59 }
60
61 } // namespace adapter
62 } // namespace http2
63