| 1308 | const CommonStrings* get_common_strings(); |
| 1309 | |
| 1310 | static void PackH2Message(butil::IOBuf* out, |
| 1311 | butil::IOBuf& headers, |
| 1312 | butil::IOBuf& trailer_headers, |
| 1313 | const butil::IOBuf& data, |
| 1314 | int stream_id, |
| 1315 | H2Context* conn_ctx) { |
| 1316 | const H2Settings& remote_settings = conn_ctx->remote_settings(); |
| 1317 | char headbuf[FRAME_HEAD_SIZE]; |
| 1318 | H2FrameHead headers_head = { |
| 1319 | (uint32_t)headers.size(), H2_FRAME_HEADERS, 0, stream_id}; |
| 1320 | if (data.empty() && trailer_headers.empty()) { |
| 1321 | headers_head.flags |= H2_FLAGS_END_STREAM; |
| 1322 | } |
| 1323 | if (headers_head.payload_size <= remote_settings.max_frame_size) { |
| 1324 | headers_head.flags |= H2_FLAGS_END_HEADERS; |
| 1325 | SerializeFrameHead(headbuf, headers_head); |
| 1326 | out->append(headbuf, sizeof(headbuf)); |
| 1327 | out->append(butil::IOBuf::Movable(headers)); |
| 1328 | } else { |
| 1329 | headers_head.payload_size = remote_settings.max_frame_size; |
| 1330 | SerializeFrameHead(headbuf, headers_head); |
| 1331 | out->append(headbuf, sizeof(headbuf)); |
| 1332 | headers.cutn(out, headers_head.payload_size); |
| 1333 | |
| 1334 | H2FrameHead cont_head = {0, H2_FRAME_CONTINUATION, 0, stream_id}; |
| 1335 | while (!headers.empty()) { |
| 1336 | if (headers.size() <= remote_settings.max_frame_size) { |
| 1337 | cont_head.flags |= H2_FLAGS_END_HEADERS; |
| 1338 | cont_head.payload_size = headers.size(); |
| 1339 | } else { |
| 1340 | cont_head.payload_size = remote_settings.max_frame_size; |
| 1341 | } |
| 1342 | SerializeFrameHead(headbuf, cont_head); |
| 1343 | out->append(headbuf, FRAME_HEAD_SIZE); |
| 1344 | headers.cutn(out, cont_head.payload_size); |
| 1345 | } |
| 1346 | } |
| 1347 | if (!data.empty()) { |
| 1348 | H2FrameHead data_head = {0, H2_FRAME_DATA, 0, stream_id}; |
| 1349 | butil::IOBufBytesIterator it(data); |
| 1350 | while (it.bytes_left()) { |
| 1351 | if (it.bytes_left() <= remote_settings.max_frame_size) { |
| 1352 | data_head.payload_size = it.bytes_left(); |
| 1353 | if (trailer_headers.empty()) { |
| 1354 | data_head.flags |= H2_FLAGS_END_STREAM; |
| 1355 | } |
| 1356 | } else { |
| 1357 | data_head.payload_size = remote_settings.max_frame_size; |
| 1358 | } |
| 1359 | SerializeFrameHead(headbuf, data_head); |
| 1360 | out->append(headbuf, FRAME_HEAD_SIZE); |
| 1361 | it.append_and_forward(out, data_head.payload_size); |
| 1362 | } |
| 1363 | } |
| 1364 | if (!trailer_headers.empty()) { |
| 1365 | H2FrameHead headers_head = { |
| 1366 | (uint32_t)trailer_headers.size(), H2_FRAME_HEADERS, 0, stream_id}; |
| 1367 | headers_head.flags |= H2_FLAGS_END_STREAM; |
no test coverage detected