void test_nghttp2_frame_pack_push_promise() { nghttp2_hd_deflater deflater; nghttp2_hd_inflater inflater; nghttp2_push_promise frame, oframe; nghttp2_bufs bufs; nghttp2_nv *nva; ssize_t nvlen; nva_out out; ssize_t hdblocklen; int rv; frame_pack_bufs_init(&bufs); nva_out_init(&out); nghttp2_hd_deflate_init(&deflater); nghttp2_hd_inflate_init(&inflater); nva = headers(); nvlen = HEADERS_LENGTH; nghttp2_frame_push_promise_init(&frame, NGHTTP2_FLAG_END_HEADERS, 1000000007, (1U << 31) - 1, nva, nvlen); rv = nghttp2_frame_pack_push_promise(&bufs, &frame, &deflater); CU_ASSERT(0 == rv); CU_ASSERT(nghttp2_bufs_len(&bufs) > 0); CU_ASSERT(0 == unpack_framebuf((nghttp2_frame*)&oframe, &bufs)); check_frame_header(nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN, NGHTTP2_PUSH_PROMISE, NGHTTP2_FLAG_END_HEADERS, 1000000007, &oframe.hd); CU_ASSERT((1U << 31) - 1 == oframe.promised_stream_id); hdblocklen = nghttp2_bufs_len(&bufs) - NGHTTP2_FRAME_HDLEN - 4; CU_ASSERT(hdblocklen == inflate_hd(&inflater, &out, &bufs, NGHTTP2_FRAME_HDLEN + 4)); CU_ASSERT(7 == out.nvlen); CU_ASSERT(nvnameeq("method", &out.nva[0])); CU_ASSERT(nvvalueeq("GET", &out.nva[0])); nva_out_reset(&out); nghttp2_bufs_free(&bufs); nghttp2_frame_push_promise_free(&oframe); nghttp2_frame_push_promise_free(&frame); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); }
int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags _U_, int32_t stream_id, const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data) { nghttp2_outbound_item *item; nghttp2_frame *frame; nghttp2_nv *nva_copy; uint8_t flags_copy; int32_t promised_stream_id; int rv; nghttp2_mem *mem; mem = &session->mem; if (stream_id == 0 || nghttp2_session_is_my_stream_id(session, stream_id)) { return NGHTTP2_ERR_INVALID_ARGUMENT; } if (!session->server) { return NGHTTP2_ERR_PROTO; } /* All 32bit signed stream IDs are spent. */ if (session->next_stream_id > INT32_MAX) { return NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE; } item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); if (item == NULL) { return NGHTTP2_ERR_NOMEM; } nghttp2_outbound_item_init(item); item->aux_data.headers.stream_user_data = promised_stream_user_data; frame = &item->frame; rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem); if (rv < 0) { nghttp2_mem_free(mem, item); return rv; } flags_copy = NGHTTP2_FLAG_END_HEADERS; promised_stream_id = (int32_t)session->next_stream_id; session->next_stream_id += 2; nghttp2_frame_push_promise_init(&frame->push_promise, flags_copy, stream_id, promised_stream_id, nva_copy, nvlen); rv = nghttp2_session_add_item(session, item); if (rv != 0) { nghttp2_frame_push_promise_free(&frame->push_promise, mem); nghttp2_mem_free(mem, item); return rv; } return promised_stream_id; }