diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index cbddc1ab..752594b7 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -487,11 +487,7 @@ typedef enum { /** * The PRIORITY flag. */ - NGHTTP2_FLAG_PRIORITY = 0x20, - /** - * THE COMPRESSED flag. - */ - NGHTTP2_FLAG_COMPRESSED = 0x20 + NGHTTP2_FLAG_PRIORITY = 0x20 } nghttp2_flag; /** @@ -515,14 +511,10 @@ typedef enum { * SETTINGS_INITIAL_WINDOW_SIZE */ NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4, - /** - * SETTINGS_COMPRESS_DATA - */ - NGHTTP2_SETTINGS_COMPRESS_DATA = 5, /** * Maximum ID of :type:`nghttp2_settings_id`. */ - NGHTTP2_SETTINGS_MAX = 5 + NGHTTP2_SETTINGS_MAX = 4 } nghttp2_settings_id; /** @@ -645,11 +637,7 @@ typedef enum { /** * Indicates EOF was sensed. */ - NGHTTP2_DATA_FLAG_EOF = 0x01, - /** - * Indicates data was compressed by application. - */ - NGHTTP2_DATA_FLAG_COMPRESSED = 0x02 + NGHTTP2_DATA_FLAG_EOF = 0x01 } nghttp2_data_flag; /** @@ -662,11 +650,6 @@ typedef enum { * them in |buf| and return number of data stored in |buf|. If EOF is * reached, set :enum:`NGHTTP2_DATA_FLAG_EOF` flag in |*data_flags|. * - * To send compressed data payload without affecting content-length, - * set :enum:`NGHTTP2_DATA_FLAG_COMPRESSED` flag in |*data_flags|. - * Compression must be done by application prior to fill data in - * |buf|. - * * If the application wants to postpone DATA frames (e.g., * asynchronous I/O, or reading data blocks for long time), it is * achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index 1c0e9bcc..7ef34193 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -1022,7 +1022,6 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: break; case NGHTTP2_SETTINGS_ENABLE_PUSH: - case NGHTTP2_SETTINGS_COMPRESS_DATA: if(iv[i].value != 0 && iv[i].value != 1) { return 0; } diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 4d7e9c80..d4761aaa 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -229,7 +229,6 @@ static void init_settings(uint32_t *settings) NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS; settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] = NGHTTP2_INITIAL_WINDOW_SIZE; - settings[NGHTTP2_SETTINGS_COMPRESS_DATA] = 0; } static void active_outbound_item_reset(nghttp2_active_outbound_item *aob) @@ -3423,12 +3422,6 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, (session, frame, NGHTTP2_FLOW_CONTROL_ERROR); } break; - case NGHTTP2_SETTINGS_COMPRESS_DATA: - if(entry->value != 0 && entry->value != 1) { - return session_handle_invalid_connection - (session, frame, NGHTTP2_PROTOCOL_ERROR); - } - break; } session->remote_settings[entry->settings_id] = entry->value; } @@ -4013,11 +4006,6 @@ static int session_on_data_received_fail_fast(nghttp2_session *session) goto fail; } - if((iframe->frame.hd.flags & NGHTTP2_FLAG_COMPRESSED) && - session->local_settings[NGHTTP2_SETTINGS_COMPRESS_DATA] == 0) { - goto fail; - } - if(nghttp2_session_is_my_stream_id(session, stream_id)) { if(stream->state == NGHTTP2_STREAM_CLOSING) { return NGHTTP2_ERR_IGN_PAYLOAD; @@ -4088,7 +4076,6 @@ static int inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) case NGHTTP2_SETTINGS_ENABLE_PUSH: case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - case NGHTTP2_SETTINGS_COMPRESS_DATA: break; default: return -1; @@ -4238,8 +4225,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, iframe->frame.hd.flags &= (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT | NGHTTP2_FLAG_PAD_LOW | - NGHTTP2_FLAG_PAD_HIGH | - NGHTTP2_FLAG_COMPRESSED); + NGHTTP2_FLAG_PAD_HIGH); /* Check stream is open. If it is not open or closing, ignore payload. */ busy = 1; @@ -5560,10 +5546,6 @@ int nghttp2_session_pack_data(nghttp2_session *session, } } - if(data_flags & NGHTTP2_DATA_FLAG_COMPRESSED) { - flags |= NGHTTP2_FLAG_COMPRESSED; - } - /* The primary reason of data_frame is pass to the user callback */ data_frame.hd.length = payloadlen; data_frame.hd.stream_id = frame->hd.stream_id; diff --git a/src/HttpServer.cc b/src/HttpServer.cc index c7a8bbf3..38187592 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -120,8 +120,7 @@ Stream::Stream(Http2Handler *handler, int32_t stream_id) rtimer(nullptr), wtimer(nullptr), stream_id(stream_id), - file(-1), - enable_compression(false) + file(-1) {} Stream::~Stream() @@ -726,12 +725,10 @@ int Http2Handler::on_connect() return r; } nghttp2_settings_entry entry[4]; - size_t niv = 2; + size_t niv = 1; entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; entry[0].value = 100; - entry[1].settings_id = NGHTTP2_SETTINGS_COMPRESS_DATA; - entry[1].value = 1; if(sessions_->get_config()->header_table_size >= 0) { entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; @@ -949,19 +946,6 @@ void Http2Handler::terminate_session(nghttp2_error_code error_code) nghttp2_session_terminate_session(session_, error_code); } -void Http2Handler::decide_compression(const std::string& path, Stream *stream) -{ - if(nghttp2_session_get_remote_settings - (session_, NGHTTP2_SETTINGS_COMPRESS_DATA) == 1 && - (util::endsWith(path, ".html") || - util::endsWith(path, ".js") || - util::endsWith(path, ".css") || - util::endsWith(path, ".txt"))) { - - stream->enable_compression = true; - } -} - ssize_t file_read_callback (nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, uint32_t *data_flags, @@ -972,44 +956,16 @@ ssize_t file_read_callback int fd = source->fd; ssize_t nread; - ssize_t rv; - // Compressing too small data is not efficient? - if(length >= 1024 && stream && stream->enable_compression) { - uint8_t srcbuf[4096]; - auto maxread = std::min(length, sizeof(srcbuf)); + while((nread = read(fd, buf, length)) == -1 && errno == EINTR); - while((nread = read(fd, srcbuf, maxread)) == -1 && errno == EINTR); - if(nread == -1) { - if(stream) { - remove_stream_read_timeout(stream); - remove_stream_write_timeout(stream); - } - - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + if(nread == -1) { + if(stream) { + remove_stream_read_timeout(stream); + remove_stream_write_timeout(stream); } - if(nread > 0) { - rv = deflate_data(buf, length, srcbuf, nread); - - if(rv < 0) { - memcpy(buf, srcbuf, nread); - } else { - nread = rv; - - *data_flags |= NGHTTP2_DATA_FLAG_COMPRESSED; - } - } - } else { - while((nread = read(fd, buf, length)) == -1 && errno == EINTR); - if(nread == -1) { - if(stream) { - remove_stream_read_timeout(stream); - remove_stream_write_timeout(stream); - } - - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } if(nread == 0) { @@ -1125,26 +1081,34 @@ void prepare_response(Stream *stream, Http2Handler *hd, bool allow_push = true) int file = open(path.c_str(), O_RDONLY | O_BINARY); if(file == -1) { prepare_status_response(stream, hd, STATUS_404); - } else { - struct stat buf; - if(fstat(file, &buf) == -1) { - close(file); - prepare_status_response(stream, hd, STATUS_404); - } else { - stream->file = file; - nghttp2_data_provider data_prd; - data_prd.source.fd = file; - data_prd.read_callback = file_read_callback; - if(last_mod_found && buf.st_mtime <= last_mod) { - prepare_status_response(stream, hd, STATUS_304); - } else { - hd->decide_compression(path, stream); - hd->submit_file_response(STATUS_200, stream, buf.st_mtime, - buf.st_size, &data_prd); - } - } + return; } + + struct stat buf; + + if(fstat(file, &buf) == -1) { + close(file); + prepare_status_response(stream, hd, STATUS_404); + + return; + } + + stream->file = file; + + nghttp2_data_provider data_prd; + + data_prd.source.fd = file; + data_prd.read_callback = file_read_callback; + + if(last_mod_found && buf.st_mtime <= last_mod) { + prepare_status_response(stream, hd, STATUS_304); + + return; + } + + hd->submit_file_response(STATUS_200, stream, buf.st_mtime, + buf.st_size, &data_prd); } } // namespace diff --git a/src/HttpServer.h b/src/HttpServer.h index 2af4ad61..efba5434 100644 --- a/src/HttpServer.h +++ b/src/HttpServer.h @@ -88,7 +88,6 @@ struct Stream { event *wtimer; int32_t stream_id; int file; - bool enable_compression; Stream(Http2Handler *handler, int32_t stream_id); ~Stream(); }; @@ -140,7 +139,6 @@ public: void remove_settings_timer(); void terminate_session(nghttp2_error_code error_code); int tls_handshake(); - void decide_compression(const std::string& path, Stream *stream); private: int handle_ssl_temporal_error(int err); int tls_write(const uint8_t *data, size_t datalen); diff --git a/src/app_helper.cc b/src/app_helper.cc index 0ef9484a..c07caa26 100644 --- a/src/app_helper.cc +++ b/src/app_helper.cc @@ -99,8 +99,6 @@ const char* strsettingsid(int32_t id) return "SETTINGS_MAX_CONCURRENT_STREAMS"; case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: return "SETTINGS_INITIAL_WINDOW_SIZE"; - case NGHTTP2_SETTINGS_COMPRESS_DATA: - return "SETTINGS_COMPRESS_DATA"; default: return "UNKNOWN"; } @@ -243,12 +241,6 @@ void print_flags(const nghttp2_frame_hd& hd) } s += "PAD_HIGH"; } - if(hd.flags & NGHTTP2_FLAG_COMPRESSED) { - if(!s.empty()) { - s += " | "; - } - s += "COMPRESSED"; - } break; case NGHTTP2_HEADERS: if(hd.flags & NGHTTP2_FLAG_END_STREAM) { diff --git a/src/nghttp.cc b/src/nghttp.cc index 80dd1311..f9f61498 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -100,7 +100,7 @@ struct Config { bool stat; bool upgrade; bool continuation; - bool compress_data; + Config() : output_upper_thres(1024*1024), padding(0), @@ -117,8 +117,7 @@ struct Config { get_assets(false), stat(false), upgrade(false), - continuation(false), - compress_data(false) + continuation(false) { nghttp2_option_new(&http2_option); nghttp2_option_set_peer_max_concurrent_streams @@ -347,7 +346,7 @@ Config config; namespace { size_t populate_settings(nghttp2_settings_entry *iv) { - size_t niv = 3; + size_t niv = 2; iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; iv[0].value = 100; @@ -359,9 +358,6 @@ size_t populate_settings(nghttp2_settings_entry *iv) iv[1].value = NGHTTP2_INITIAL_WINDOW_SIZE; } - iv[2].settings_id = NGHTTP2_SETTINGS_COMPRESS_DATA; - iv[2].value = 1; - if(config.header_table_size >= 0) { iv[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; iv[niv].value = config.header_table_size; @@ -1184,65 +1180,15 @@ int on_data_chunk_recv_callback data += tlen; len -= tlen; } - } else if(flags & NGHTTP2_FLAG_COMPRESSED) { - if(len == 0 || !client->check_inflater(stream_id)) { - return 0; - } - const size_t MAX_OUTLEN = 4096; - uint8_t out[MAX_OUTLEN]; - size_t outlen; - - do { - outlen = MAX_OUTLEN; - auto tlen = len; - - int rv = nghttp2_gzip_inflate(client->inflater, out, &outlen, - data, &tlen); - if(rv != 0) { - goto per_frame_decomp_error; - } - - if(!config.null_out) { - std::cout.write(reinterpret_cast(out), outlen); - } - - update_html_parser(client, req, out, outlen, 0); - - data += tlen; - len -= tlen; - - if(nghttp2_gzip_inflate_finished(client->inflater)) { - // When Z_STREAM_END was reached, remaining input length - // must be 0. - if(len > 0) { - goto per_frame_decomp_error; - } - - break; - } - } while(len > 0 || outlen > 0); - - } else { - if(!config.null_out) { - std::cout.write(reinterpret_cast(data), len); - } - update_html_parser(client, req, data, len, 0); + return 0; } - return 0; - - per_frame_decomp_error: - // If per-frame decompression failed, we remember the stream ID so - // that subsequent chunk of DATA is ignored. - client->last_inflate_error_stream_id = stream_id; - - if(!client->reset_inflater()) { - return NGHTTP2_ERR_CALLBACK_FAILURE; + if(!config.null_out) { + std::cout.write(reinterpret_cast(data), len); } - nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, stream_id, - NGHTTP2_INTERNAL_ERROR); + update_html_parser(client, req, data, len, 0); return 0; } @@ -1379,28 +1325,6 @@ int on_frame_recv_callback2 auto client = get_session(user_data); switch(frame->hd.type) { - case NGHTTP2_DATA: - if(frame->hd.flags & NGHTTP2_FLAG_COMPRESSED) { - - auto inflate_finished = nghttp2_gzip_inflate_finished(client->inflater); - - if(!client->reset_inflater()) { - rv = nghttp2_session_terminate_session(session, - NGHTTP2_INTERNAL_ERROR); - - if(nghttp2_is_fatal(rv)) { - rv = NGHTTP2_ERR_CALLBACK_FAILURE; - } else { - rv = 0; - } - } - // Error if compressed block does not end in frame. - if(!inflate_finished) { - nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, - frame->hd.stream_id, NGHTTP2_PROTOCOL_ERROR); - } - } - break; case NGHTTP2_HEADERS: { if(frame->headers.cat != NGHTTP2_HCAT_RESPONSE && frame->headers.cat != NGHTTP2_HCAT_PUSH_RESPONSE) { @@ -1820,37 +1744,12 @@ ssize_t file_read_callback assert(req); int fd = source->fd; ssize_t nread; - ssize_t rv; - // Compressing too small data is not efficient? - if(length >= 1024 && config.compress_data && - nghttp2_session_get_remote_settings - (session, NGHTTP2_SETTINGS_COMPRESS_DATA) == 1) { - uint8_t srcbuf[4096]; - auto maxread = std::min(length, sizeof(srcbuf)); + while((nread = pread(fd, buf, length, req->data_offset)) == -1 && + errno == EINTR); - while((nread = read(fd, srcbuf, maxread)) == -1 && errno == EINTR); - if(nread == -1) { - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } - - if(nread > 0) { - rv = deflate_data(buf, length, srcbuf, nread); - - if(rv < 0) { - memcpy(buf, srcbuf, nread); - } else { - nread = rv; - - *data_flags |= NGHTTP2_DATA_FLAG_COMPRESSED; - } - } - } else { - while((nread = pread(fd, buf, length, req->data_offset)) == -1 && - errno == EINTR); - if(nread == -1) { - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } + if(nread == -1) { + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } if(nread == 0) { @@ -1992,9 +1891,6 @@ Options: be in PEM format. -d, --data= Post FILE to server. If '-' is given, data will be read from stdin. - -g, --compress-data - When used with -d option, compress request body - on the fly using per-frame compression. -m, --multiply= Request each URI times. By default, same URI is not requested twice. This option disables it too. @@ -2042,7 +1938,6 @@ int main(int argc, char **argv) {"help", no_argument, nullptr, 'h'}, {"header", required_argument, nullptr, 'H'}, {"data", required_argument, nullptr, 'd'}, - {"compress-data", no_argument, nullptr, 'g'}, {"multiply", required_argument, nullptr, 'm'}, {"upgrade", no_argument, nullptr, 'u'}, {"weight", required_argument, nullptr, 'p'}, @@ -2162,9 +2057,6 @@ int main(int argc, char **argv) case 'd': config.datafile = strcmp("-", optarg) == 0 ? "/dev/stdin" : optarg; break; - case 'g': - config.compress_data = true; - break; case 'm': config.multiply = strtoul(optarg, nullptr, 10); break; diff --git a/tests/nghttp2_frame_test.c b/tests/nghttp2_frame_test.c index 1f7fb3f1..28080c87 100644 --- a/tests/nghttp2_frame_test.c +++ b/tests/nghttp2_frame_test.c @@ -634,15 +634,6 @@ void test_nghttp2_iv_check(void) iv[1].value = 3; CU_ASSERT(!nghttp2_iv_check(iv, 2)); - /* COMPRESSED_DATA only allows 0 or 1 */ - iv[1].settings_id = NGHTTP2_SETTINGS_COMPRESS_DATA; - iv[1].value = 0; - CU_ASSERT(nghttp2_iv_check(iv, 2)); - iv[1].value = 1; - CU_ASSERT(nghttp2_iv_check(iv, 2)); - iv[1].value = 3; - CU_ASSERT(!nghttp2_iv_check(iv, 2)); - /* Undefined SETTINGS ID */ iv[1].settings_id = 1000000009; iv[1].value = 0; diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 9e6a29ca..ed77510d 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -75,7 +75,6 @@ typedef struct { nghttp2_nv nv; size_t data_chunk_len; size_t padding_boundary; - int compress_data; } my_user_data; static void scripted_data_feed_init2(scripted_data_feed *df, @@ -250,24 +249,6 @@ static ssize_t fixed_length_data_source_read_callback return wlen; } -static ssize_t compressed_fixed_length_data_source_read_callback -(nghttp2_session *session, int32_t stream_id, - uint8_t *buf, size_t len, uint32_t *data_flags, - nghttp2_data_source *source, void *user_data) -{ - my_user_data *ud = (my_user_data*)user_data; - size_t wlen; - - wlen = fixed_length_data_source_read_callback - (session, stream_id, buf, len, data_flags, source, user_data); - - if(ud->compress_data) { - *data_flags |= NGHTTP2_DATA_FLAG_COMPRESSED; - } - - return wlen; -} - static ssize_t temporal_failure_data_source_read_callback (nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t len, uint32_t *data_flags, @@ -722,57 +703,6 @@ void test_nghttp2_session_recv_data(void) CU_ASSERT(NGHTTP2_PROTOCOL_ERROR == OB_CTRL(item)->goaway.error_code); nghttp2_session_del(session); - - /* Receiving compressed DATA while SETTINGS_COMPRESS_DATA == 0 is - subject to connection error */ - - nghttp2_session_client_new(&session, &callbacks, &ud); - - hd.length = 4096; - hd.type = NGHTTP2_DATA; - hd.flags = NGHTTP2_FLAG_COMPRESSED; - hd.stream_id = 1; - nghttp2_frame_pack_frame_hd(data, &hd); - - stream = nghttp2_session_open_stream(session, 1, - NGHTTP2_STREAM_FLAG_NONE, - &pri_spec_default, - NGHTTP2_STREAM_OPENED, NULL); - - ud.data_chunk_recv_cb_called = 0; - ud.frame_recv_cb_called = 0; - rv = nghttp2_session_mem_recv(session, data, 8+4096); - CU_ASSERT(8+4096 == rv); - - CU_ASSERT(0 == ud.data_chunk_recv_cb_called); - CU_ASSERT(0 == ud.frame_recv_cb_called); - item = nghttp2_session_get_next_ob_item(session); - CU_ASSERT(NGHTTP2_GOAWAY == OB_CTRL_TYPE(item)); - - nghttp2_session_del(session); - - /* Receiving compressed DATA while SETTINGS_COMPRESS_DATA == 1 is - allowed */ - - nghttp2_session_client_new(&session, &callbacks, &ud); - - session->local_settings[NGHTTP2_SETTINGS_COMPRESS_DATA] = 1; - - stream = nghttp2_session_open_stream(session, 1, - NGHTTP2_STREAM_FLAG_NONE, - &pri_spec_default, - NGHTTP2_STREAM_OPENED, NULL); - - ud.data_chunk_recv_cb_called = 0; - ud.frame_recv_cb_called = 0; - rv = nghttp2_session_mem_recv(session, data, 8+4096); - CU_ASSERT(8+4096 == rv); - - CU_ASSERT(1 == ud.data_chunk_recv_cb_called); - CU_ASSERT(1 == ud.frame_recv_cb_called); - CU_ASSERT(NULL == nghttp2_session_get_next_ob_item(session)); - - nghttp2_session_del(session); } void test_nghttp2_session_recv_continuation(void) @@ -2699,14 +2629,12 @@ void test_nghttp2_submit_data(void) memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); callbacks.send_callback = block_count_send_callback; - data_prd.read_callback = compressed_fixed_length_data_source_read_callback; + data_prd.read_callback = fixed_length_data_source_read_callback; ud.data_source_length = NGHTTP2_DATA_PAYLOADLEN * 2; CU_ASSERT(0 == nghttp2_session_client_new(&session, &callbacks, &ud)); aob = &session->aob; framebufs = &aob->framebufs; - session->remote_settings[NGHTTP2_SETTINGS_COMPRESS_DATA] = 1; - nghttp2_session_open_stream(session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec_default, NGHTTP2_STREAM_OPENING, NULL); @@ -2714,8 +2642,6 @@ void test_nghttp2_submit_data(void) NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT, 1, &data_prd)); - /* First, no compression */ - ud.compress_data = 0; ud.block_count = 0; CU_ASSERT(0 == nghttp2_session_send(session)); data_frame = nghttp2_outbound_item_get_data_frame(aob->item); @@ -2728,21 +2654,6 @@ void test_nghttp2_submit_data(void) CU_ASSERT((NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT) == data_frame->hd.flags); - /* Now compression enabled */ - ud.compress_data = 1; - ud.block_count = 1; - CU_ASSERT(0 == nghttp2_session_send(session)); - data_frame = nghttp2_outbound_item_get_data_frame(aob->item); - nghttp2_frame_unpack_frame_hd(&hd, buf->pos); - - /* This is the last frame, so we must have following flags */ - CU_ASSERT((NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT | - NGHTTP2_FLAG_COMPRESSED) == hd.flags); - /* frame->hd.flags has these flags */ - CU_ASSERT((NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_SEGMENT | - NGHTTP2_FLAG_COMPRESSED) == - data_frame->hd.flags); - nghttp2_session_del(session); }