Commit 1db21953 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Implement padding for HEADERS and CONTINUATION

parent 10feab02
......@@ -151,9 +151,9 @@ typedef struct {
* @macro
*
* The default value of DATA padding alignment. See
* :member:`NGHTTP2_OPT_DATA_PAD_ALIGNMENT`.
* :member:`NGHTTP2_OPT_PAD_ALIGNMENT`.
*/
#define NGHTTP2_DATA_PAD_ALIGNMENT 256
#define NGHTTP2_PAD_ALIGNMENT 256
/**
* @enum
......@@ -655,6 +655,11 @@ typedef struct {
* The frame header.
*/
nghttp2_frame_hd hd;
/**
* The length of the padding in this frame. This includes PAD_HIGH
* and PAD_LOW.
*/
size_t padlen;
/**
* The name/value pairs.
*/
......@@ -746,6 +751,11 @@ typedef struct {
* The frame header.
*/
nghttp2_frame_hd hd;
/**
* The length of the padding in this frame. This includes PAD_HIGH
* and PAD_LOW.
*/
size_t padlen;
/**
* The name/value pairs.
*/
......@@ -1324,13 +1334,14 @@ typedef enum {
*/
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 2,
/**
* This option specifies the alignment of padding in DATA frame. If
* this option is set to N, padding is added to DATA payload so that
* its payload length is divisible by N. Due to flow control,
* padding is not always added according to this alignment. The
* option value must be greater than or equal to 8.
* This option specifies the alignment of padding in frame
* payload. If this option is set to N, padding is added to frame
* payload so that its payload length is divisible by N. For DATA
* frame, due to flow control, padding is not always added according
* to this alignment. The option value must be greater than or equal
* to 8.
*/
NGHTTP2_OPT_DATA_PAD_ALIGNMENT = 1 << 3
NGHTTP2_OPT_PAD_ALIGNMENT = 1 << 3
} nghttp2_opt;
/**
......@@ -1352,9 +1363,9 @@ typedef struct {
*/
uint8_t no_auto_connection_window_update;
/**
* :enum:`NGHTTP2_OPT_DATA_PAD_ALIGNMENT`
* :enum:`NGHTTP2_OPT_PAD_ALIGNMENT`
*/
uint16_t data_pad_alignment;
uint16_t pad_alignment;
} nghttp2_opt_set;
/**
......
......@@ -193,9 +193,9 @@ void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata)
}
}
size_t nghttp2_frame_data_trail_padlen(nghttp2_data *frame)
size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen)
{
return frame->padlen
return padlen
- ((frame->hd.flags & NGHTTP2_FLAG_PAD_HIGH) > 0)
- ((frame->hd.flags & NGHTTP2_FLAG_PAD_LOW) > 0);
}
......@@ -214,19 +214,6 @@ void nghttp2_frame_private_data_init(nghttp2_private_data *frame,
void nghttp2_frame_private_data_free(nghttp2_private_data *frame)
{}
/*
* Returns the offset of the name/header block in the HEADERS frame,
* including frame header length.
*/
static size_t headers_nv_offset(nghttp2_headers *frame)
{
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
return NGHTTP2_FRAME_HEAD_LENGTH + 4;
} else {
return NGHTTP2_FRAME_HEAD_LENGTH;
}
}
size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame)
{
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
......@@ -238,23 +225,41 @@ size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame)
ssize_t nghttp2_frame_pack_headers(uint8_t **buf_ptr,
size_t *buflen_ptr,
size_t *bufoff_ptr,
nghttp2_headers *frame,
nghttp2_hd_deflater *deflater)
nghttp2_hd_deflater *deflater,
size_t align)
{
ssize_t framelen;
size_t nv_offset = headers_nv_offset(frame);
size_t payloadoff = NGHTTP2_FRAME_HEAD_LENGTH + 2;
size_t nv_offset =
payloadoff + nghttp2_frame_headers_payload_nv_offset(frame);
ssize_t rv;
size_t payloadlen;
rv = nghttp2_hd_deflate_hd(deflater, buf_ptr, buflen_ptr, nv_offset,
frame->nva, frame->nvlen);
if(rv < 0) {
return rv;
}
framelen = rv + nv_offset;
if(NGHTTP2_FRAME_HEAD_LENGTH + NGHTTP2_MAX_FRAME_LENGTH < rv + nv_offset) {
frame->hd.length = NGHTTP2_MAX_FRAME_LENGTH;
frame->hd.flags &= ~NGHTTP2_FLAG_END_HEADERS;
payloadlen = nghttp2_frame_headers_payload_nv_offset(frame) + rv;
if(align > 0) {
ssize_t padlen;
padlen = nghttp2_frame_add_pad(buf_ptr, buflen_ptr, bufoff_ptr,
&frame->hd.flags,
payloadlen,
payloadlen + align,
align);
if(padlen < 0) {
return padlen;
}
frame->padlen = padlen;
frame->hd.length = payloadlen + padlen;
} else {
frame->hd.length = framelen - NGHTTP2_FRAME_HEAD_LENGTH;
*bufoff_ptr = 2;
frame->padlen = 0;
frame->hd.length = payloadlen;
}
/* If frame->nvlen == 0, *buflen_ptr may be smaller than
nv_offset */
......@@ -262,13 +267,21 @@ ssize_t nghttp2_frame_pack_headers(uint8_t **buf_ptr,
if(rv < 0) {
return rv;
}
memset(*buf_ptr, 0, nv_offset);
memset(*buf_ptr + *bufoff_ptr, 0, NGHTTP2_FRAME_HEAD_LENGTH);
/* pack ctrl header after length is determined */
nghttp2_frame_pack_frame_hd(*buf_ptr, &frame->hd);
if(NGHTTP2_FRAME_HEAD_LENGTH + NGHTTP2_MAX_FRAME_LENGTH < rv + nv_offset) {
/* Needs CONTINUATION */
nghttp2_frame_hd hd = frame->hd;
hd.flags &= ~(NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW);
nghttp2_frame_pack_frame_hd(*buf_ptr + *bufoff_ptr, &hd);
} else {
nghttp2_frame_pack_frame_hd(*buf_ptr + *bufoff_ptr, &frame->hd);
}
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
nghttp2_put_uint32be(&(*buf_ptr)[8], frame->pri);
nghttp2_put_uint32be(&(*buf_ptr)[payloadoff], frame->pri);
}
return framelen;
return frame->hd.length + NGHTTP2_FRAME_HEAD_LENGTH + *bufoff_ptr;
}
int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
......@@ -276,7 +289,6 @@ int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
size_t payloadlen)
{
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
assert(payloadlen == 4);
frame->pri = nghttp2_get_uint32(payload) & NGHTTP2_PRIORITY_MASK;
} else {
frame->pri = NGHTTP2_PRI_DEFAULT;
......@@ -660,19 +672,23 @@ ssize_t nghttp2_frame_add_pad(uint8_t **buf_ptr, size_t *buflen_ptr,
payloadmax);
size_t padlen = nextlen - payloadlen;
size_t trail_padlen = 0;
size_t headoff = 2;
size_t trail_padoff = headoff + NGHTTP2_FRAME_HEAD_LENGTH + payloadlen;
/* extra 2 bytes for PAD_HIGH and PAD_LOW. */
size_t trail_padoff = 2 + NGHTTP2_FRAME_HEAD_LENGTH + payloadlen;
if(padlen > 257) {
headoff = 0;
*bufoff_ptr = 0;
trail_padlen = padlen - 2;
*flags_ptr |= NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW;
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH] = trail_padlen >> 8;
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH + 1] = trail_padlen & 0xff;
} else if(padlen > 0) {
headoff = 1;
*bufoff_ptr = 1;
trail_padlen = padlen - 1;
*flags_ptr |= NGHTTP2_FLAG_PAD_LOW;
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH + 1] = trail_padlen;
} else {
*bufoff_ptr = 2;
return 0;
}
rv = nghttp2_reserve_buffer(buf_ptr, buflen_ptr,
......@@ -682,7 +698,6 @@ ssize_t nghttp2_frame_add_pad(uint8_t **buf_ptr, size_t *buflen_ptr,
}
memset((*buf_ptr) + trail_padoff, 0, trail_padlen);
*bufoff_ptr = headoff;
return padlen;
}
......@@ -104,14 +104,21 @@ size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame);
* expansion occurred, memory previously pointed by |*buf_ptr| may
* change. |*buf_ptr| and |*buflen_ptr| are updated accordingly.
*
* The first byte the frame is serialized is returned in the
* |*bufoff_ptr|.
*
* The |align| is used as padding alignment. If the |align| is zero,
* no padding is added.
*
* frame->hd.length is assigned after length is determined during
* packing process. If payload length is strictly larger than
* NGHTTP2_MAX_FRAME_LENGTH, payload data is still serialized as is,
* but frame->hd.length is set to NGHTTP2_MAX_FRAME_LENGTH and
* NGHTTP2_FLAG_END_HEADERS flag is cleared from frame->hd.flags.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
* This function returns the size of packed frame (which includes
* |*bufoff_ptr| bytes) if it succeeds, or returns one of the
* following negative error codes:
*
* NGHTTP2_ERR_HEADER_COMP
* The deflate operation failed.
......@@ -122,8 +129,10 @@ size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame);
*/
ssize_t nghttp2_frame_pack_headers(uint8_t **buf_ptr,
size_t *buflen_ptr,
size_t *bufoff_ptr,
nghttp2_headers *frame,
nghttp2_hd_deflater *deflater);
nghttp2_hd_deflater *deflater,
size_t align);
/*
* Unpacks HEADERS frame byte sequence into |frame|. This function
......@@ -427,10 +436,11 @@ void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata);
/*
* Returns the number of padding data after application data
* payload. Thus this does not include the PAD_HIGH and PAD_LOW.
* Returns the number of padding bytes after payload. The total
* padding length is given in the |padlen|. The returned value does
* not include the PAD_HIGH and PAD_LOW.
*/
size_t nghttp2_frame_data_trail_padlen(nghttp2_data *frame);
size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen);
void nghttp2_frame_private_data_init(nghttp2_private_data *frame,
uint8_t flags,
......
This diff is collapsed.
......@@ -44,10 +44,7 @@
*/
typedef enum {
NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE = 1 << 0,
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE = 1 << 1,
/* Option to disable DATA frame padding, which is currently hidden
from outside, but provided for ease of testing */
NGHTTP2_OPTMASK_NO_DATA_PADDING = 1 << 2,
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE = 1 << 1
} nghttp2_optmask;
typedef struct {
......@@ -89,6 +86,8 @@ typedef enum {
NGHTTP2_IB_READ_GOAWAY_DEBUG,
NGHTTP2_IB_EXPECT_CONTINUATION,
NGHTTP2_IB_IGN_CONTINUATION,
NGHTTP2_IB_READ_PAD_CONTINUATION,
NGHTTP2_IB_IGN_PAD_CONTINUATION,
NGHTTP2_IB_READ_DATA,
NGHTTP2_IB_IGN_DATA
} nghttp2_inbound_state;
......@@ -105,6 +104,8 @@ typedef struct {
size_t left;
/* How many bytes we still need to receive for current frame */
size_t payloadleft;
/* padding length for the current frame */
size_t padlen;
nghttp2_inbound_state state;
/* TODO, remove this. Error code */
int error_code;
......@@ -152,8 +153,8 @@ struct nghttp2_session {
size_t num_incoming_streams;
/* The number of bytes allocated for nvbuf */
size_t nvbuflen;
/* DATA padding alignemnt. See NGHTTP2_OPT_DATA_PAD_ALIGNMENT. */
size_t data_pad_alignment;
/* padding alignemnt. See NGHTTP2_OPT_PAD_ALIGNMENT. */
size_t pad_alignment;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id;
/* The largest stream ID received so far */
......
......@@ -66,7 +66,7 @@ const std::string NGHTTPD_SERVER = "nghttpd nghttp2/" NGHTTP2_VERSION;
Config::Config()
: data_ptr(nullptr),
output_upper_thres(1024*1024),
data_pad_alignment(NGHTTP2_DATA_PAD_ALIGNMENT),
pad_alignment(NGHTTP2_PAD_ALIGNMENT),
header_table_size(-1),
port(0),
verbose(false),
......@@ -365,11 +365,11 @@ int Http2Handler::on_connect()
nghttp2_opt_set opt_set;
memset(&opt_set, 0, sizeof(opt_set));
opt_set.data_pad_alignment = sessions_->get_config()->data_pad_alignment;
opt_set.pad_alignment = sessions_->get_config()->pad_alignment;
fill_callback(callbacks, sessions_->get_config());
r = nghttp2_session_server_new2(&session_, &callbacks, this,
NGHTTP2_OPT_DATA_PAD_ALIGNMENT, &opt_set);
NGHTTP2_OPT_PAD_ALIGNMENT, &opt_set);
if(r != 0) {
return r;
}
......
......@@ -56,7 +56,7 @@ struct Config {
std::string cert_file;
void *data_ptr;
size_t output_upper_thres;
size_t data_pad_alignment;
size_t pad_alignment;
ssize_t header_table_size;
uint16_t port;
bool verbose;
......
......@@ -244,6 +244,18 @@ void print_flags(const nghttp2_frame_hd& hd)
}
s += "PRIORITY";
}
if(hd.flags & NGHTTP2_FLAG_PAD_LOW) {
if(!s.empty()) {
s += " | ";
}
s += "PAD_LOW";
}
if(hd.flags & NGHTTP2_FLAG_PAD_HIGH) {
if(!s.empty()) {
s += " | ";
}
s += "PAD_HIGH";
}
break;
case NGHTTP2_SETTINGS:
if(hd.flags & NGHTTP2_FLAG_ACK) {
......@@ -254,6 +266,18 @@ void print_flags(const nghttp2_frame_hd& hd)
if(hd.flags & NGHTTP2_FLAG_END_PUSH_PROMISE) {
s += "END_PUSH_PROMISE";
}
if(hd.flags & NGHTTP2_FLAG_PAD_LOW) {
if(!s.empty()) {
s += " | ";
}
s += "PAD_LOW";
}
if(hd.flags & NGHTTP2_FLAG_PAD_HIGH) {
if(!s.empty()) {
s += " | ";
}
s += "PAD_HIGH";
}
break;
case NGHTTP2_PING:
if(hd.flags & NGHTTP2_FLAG_ACK) {
......@@ -297,10 +321,9 @@ void print_frame(print_type ptype, const nghttp2_frame *frame)
}
break;
case NGHTTP2_HEADERS:
if(frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
print_frame_attr_indent();
printf("(pri=%d)\n", frame->headers.pri);
}
print_frame_attr_indent();
printf("(pri=%d, padlen=%zu)\n",
frame->headers.pri, frame->headers.padlen);
switch(frame->headers.cat) {
case NGHTTP2_HCAT_REQUEST:
print_frame_attr_indent();
......@@ -342,8 +365,9 @@ void print_frame(print_type ptype, const nghttp2_frame *frame)
break;
case NGHTTP2_PUSH_PROMISE:
print_frame_attr_indent();
printf("(promised_stream_id=%d)\n",
frame->push_promise.promised_stream_id);
printf("(promised_stream_id=%d, padlen=%zu)\n",
frame->push_promise.promised_stream_id,
frame->push_promise.padlen);
print_nv(frame->push_promise.nva, frame->push_promise.nvlen);
break;
case NGHTTP2_PING:
......
......@@ -82,7 +82,7 @@ struct Config {
std::string keyfile;
std::string datafile;
size_t output_upper_thres;
size_t data_pad_alignment;
size_t pad_alignment;
ssize_t peer_max_concurrent_streams;
ssize_t header_table_size;
int32_t pri;
......@@ -100,7 +100,7 @@ struct Config {
bool continuation;
Config()
: output_upper_thres(1024*1024),
data_pad_alignment(NGHTTP2_DATA_PAD_ALIGNMENT),
pad_alignment(NGHTTP2_PAD_ALIGNMENT),
peer_max_concurrent_streams(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS),
header_table_size(-1),
pri(NGHTTP2_PRI_DEFAULT),
......@@ -716,10 +716,10 @@ struct HttpClient {
}
nghttp2_opt_set opt_set;
opt_set.peer_max_concurrent_streams = config.peer_max_concurrent_streams;
opt_set.data_pad_alignment = config.data_pad_alignment;
opt_set.pad_alignment = config.pad_alignment;
rv = nghttp2_session_client_new2(&session, callbacks, this,
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS |
NGHTTP2_OPT_DATA_PAD_ALIGNMENT,
NGHTTP2_OPT_PAD_ALIGNMENT,
&opt_set);
if(rv != 0) {
return -1;
......@@ -1710,8 +1710,8 @@ void print_help(std::ostream& out)
<< " is large enough as it is seen as unlimited.\n"
<< " -c, --header-table-size=<N>\n"
<< " Specify decoder header table size.\n"
<< " -b, --data-pad=<ALIGNMENT>\n"
<< " Alignment of DATA frame padding.\n"
<< " -b, --pad=<ALIGNMENT>\n"
<< " Alignment of frame payload padding.\n"
<< " --color Force colored log output.\n"
<< " --continuation Send large header to test CONTINUATION.\n"
<< std::endl;
......@@ -1766,7 +1766,7 @@ int main(int argc, char **argv)
print_help(std::cout);
exit(EXIT_SUCCESS);
case 'b':
config.data_pad_alignment = strtol(optarg, nullptr, 10);
config.pad_alignment = strtol(optarg, nullptr, 10);
break;
case 'n':
config.null_out = true;
......
......@@ -115,8 +115,8 @@ void print_help(std::ostream& out)
<< " -p/=/foo.png -p/doc=/bar.css\n"
<< " PATH and PUSH_PATHs are relative to document\n"
<< " root. See --htdocs option.\n"
<< " -b, --data-pad=<ALIGNMENT>\n"
<< " Alignment of DATA frame padding.\n"
<< " -b, --pad=<ALIGNMENT>\n"
<< " Alignment of frame payload padding.\n"
<< " -h, --help Print this help.\n"
<< std::endl;
}
......@@ -155,7 +155,7 @@ int main(int argc, char **argv)
config.verify_client = true;
break;
case 'b':
config.data_pad_alignment = strtol(optarg, nullptr, 10);
config.pad_alignment = strtol(optarg, nullptr, 10);
break;
case 'd':
config.htdocs = optarg;
......
......@@ -74,6 +74,7 @@ void test_nghttp2_frame_pack_headers()
nghttp2_headers frame, oframe;
uint8_t *buf = NULL;
size_t buflen = 0;
size_t bufoff;
ssize_t framelen;
nghttp2_nv *nva;
ssize_t nvlen;
......@@ -89,17 +90,21 @@ void test_nghttp2_frame_pack_headers()
NGHTTP2_FLAG_END_STREAM|NGHTTP2_FLAG_END_HEADERS,
1000000007,
1 << 20, nva, nvlen);
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &frame, &deflater);
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 0);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf, framelen));
check_frame_header(framelen - NGHTTP2_FRAME_HEAD_LENGTH, NGHTTP2_HEADERS,
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf + bufoff,
framelen - bufoff));
check_frame_header(framelen - bufoff - NGHTTP2_FRAME_HEAD_LENGTH,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS,
1000000007, &oframe.hd);
/* We didn't include PRIORITY flag so priority is not packed */
CU_ASSERT(1 << 30 == oframe.pri);
CU_ASSERT(framelen - 8 ==
inflate_hd(&inflater, &out, buf + 8, framelen - 8));
CU_ASSERT(framelen - (ssize_t)bufoff - 8 ==
inflate_hd(&inflater, &out,
buf + bufoff + 8, framelen - bufoff - 8));
CU_ASSERT(7 == out.nvlen);
CU_ASSERT(nvnameeq("method", &out.nva[0]));
......@@ -111,10 +116,13 @@ void test_nghttp2_frame_pack_headers()
memset(&oframe, 0, sizeof(oframe));
/* Next, include PRIORITY flag */
frame.hd.flags |= NGHTTP2_FLAG_PRIORITY;
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &frame, &deflater);
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 0);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf, framelen));
check_frame_header(framelen - NGHTTP2_FRAME_HEAD_LENGTH, NGHTTP2_HEADERS,
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf + bufoff,
framelen - bufoff));
check_frame_header(framelen - bufoff - NGHTTP2_FRAME_HEAD_LENGTH,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY,
1000000007, &oframe.hd);
......@@ -140,6 +148,7 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void)
nghttp2_headers frame;
uint8_t *buf = NULL;
size_t buflen = 0;
size_t bufoff;
ssize_t framelen;
nghttp2_nv *nva;
ssize_t nvlen;
......@@ -163,7 +172,8 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void)
NGHTTP2_FLAG_END_STREAM|NGHTTP2_FLAG_END_HEADERS,
1000000007,
0, nva, nvlen);
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &frame, &deflater);
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 0);
CU_ASSERT_EQUAL(NGHTTP2_ERR_HEADER_COMP, framelen);
nghttp2_frame_headers_free(&frame);
......
This diff is collapsed.
......@@ -159,3 +159,8 @@ ssize_t inflate_hd(nghttp2_hd_inflater *inflater, nva_out *out,
nghttp2_hd_inflate_end_headers(inflater);
return initial - buflen;
}
void session_disable_pad(nghttp2_session *session)
{
session->pad_alignment = 0;
}
......@@ -29,6 +29,7 @@
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include "nghttp2_session.h"
#include "nghttp2_frame.h"
#include "nghttp2_hd.h"
......@@ -57,4 +58,6 @@ void add_out(nva_out *out, nghttp2_nv *nv);
ssize_t inflate_hd(nghttp2_hd_inflater *inflater, nva_out *out,
uint8_t *buf, size_t buflen);
void session_disable_pad(nghttp2_session *session);
#endif /* NGHTTP2_TEST_HELPER_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment