Add HPACK decoder public API

This commit is contained in:
Tatsuhiro Tsujikawa 2014-04-29 15:53:46 +09:00
parent bc50062964
commit 3b4aedd566
3 changed files with 143 additions and 75 deletions

View File

@ -2842,6 +2842,122 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len);
*/ */
int nghttp2_check_header_value(const uint8_t *value, size_t len); int nghttp2_check_header_value(const uint8_t *value, size_t len);
/* HPACK API */
struct nghttp2_hd_inflater;
/**
* @struct
*
* HPACK inflater object.
*/
typedef struct nghttp2_hd_inflater nghttp2_hd_inflater;
/**
* @function
*
* Initializes |*inflater_ptr| for inflating name/values pairs.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
/**
* @function
*
* Deallocates any resources allocated for |inflater|.
*/
void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
/**
* @function
*
* Changes header table size in the |inflater|. This may trigger
* eviction in the dynamic table.
*
* The |settings_hd_table_bufsize_max| should be the value transmitted
* in SETTINGS_HEADER_TABLE_SIZE.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
size_t settings_hd_table_bufsize_max);
/**
* @enum
*
* The flags for header inflation.
*/
typedef enum {
/**
* No flag set.
*/
NGHTTP2_HD_INFLATE_NONE = 0,
/**
* Indicates all headers were inflated.
*/
NGHTTP2_HD_INFLATE_FINAL = 1,
/**
* Indicates a header was emitted.
*/
NGHTTP2_HD_INFLATE_EMIT = (1 << 1)
} nghttp2_hd_inflate_flag;
/**
* @function
*
* Inflates name/value block stored in |in| with length |inlen|. This
* function performs decompression. For each successful emission of
* header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
* |*inflate_flags| and name/value pair is assigned to the |nv_out|
* and the function returns. The caller must not free the members of
* |nv_out|.
*
* The |nv_out| may include pointers to the memory region in the
* |in|. The caller must retain the |in| while the |nv_out| is used.
*
* The application should call this function repeatedly until the
* `(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL` is nonzero and return
* value is non-negative. This means the all input values are
* processed successfully. Then the application must call
* `nghttp2_hd_inflate_end_headers()` to prepare for the next header
* block input.
*
* The caller can feed complete compressed header block. It also can
* feed it in several chunks. The caller must set |in_final| to
* nonzero if the given input is the last block of the compressed
* header.
*
* This function returns the number of bytes processed if it succeeds,
* or one of the following negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`NGHTTP2_ERR_HEADER_COMP`
* Inflation process has failed.
*/
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
uint8_t *in, size_t inlen, int in_final);
/**
* @function
*
* Signals the end of decompression for one header block.
*
* This function returns 0 if it succeeds. Currently this function
* always succeeds.
*/
int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1920,6 +1920,24 @@ int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater)
return 0; return 0;
} }
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr)
{
*inflater_ptr = malloc(sizeof(nghttp2_hd_inflater));
if(*inflater_ptr == NULL) {
return NULL;
}
return nghttp2_hd_inflate_init(*inflater_ptr);
}
void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater)
{
nghttp2_hd_inflate_free(inflater);
free(inflater);
}
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index, int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
nghttp2_nv *nv, int inc_indexing) nghttp2_nv *nv, int inc_indexing)
{ {

View File

@ -142,7 +142,7 @@ typedef struct {
uint8_t no_refset; uint8_t no_refset;
} nghttp2_hd_deflater; } nghttp2_hd_deflater;
typedef struct { struct nghttp2_hd_inflater {
nghttp2_hd_context ctx; nghttp2_hd_context ctx;
/* header name buffer */ /* header name buffer */
nghttp2_bufs namebufs; nghttp2_bufs namebufs;
@ -180,7 +180,7 @@ typedef struct {
/* nonzero if deflater requires that current entry must not be /* nonzero if deflater requires that current entry must not be
indexed */ indexed */
uint8_t no_index; uint8_t no_index;
} nghttp2_hd_inflater; };
/* /*
* Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit * Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
@ -233,27 +233,11 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater);
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater, int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
size_t deflate_hd_table_bufsize_max); size_t deflate_hd_table_bufsize_max);
/*
* Initializes |inflater| for inflating name/values pairs.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater);
/* /*
* Deallocates any resources allocated for |deflater|. * Deallocates any resources allocated for |deflater|.
*/ */
void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater); void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
/*
* Deallocates any resources allocated for |inflater|.
*/
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
/* /*
* Sets the availability of reference set in the |deflater|. If * Sets the availability of reference set in the |deflater|. If
* |no_refset| is nonzero, the deflater will first emit index=0 in the * |no_refset| is nonzero, the deflater will first emit index=0 in the
@ -279,23 +263,6 @@ void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater, int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
size_t settings_hd_table_bufsize_max); size_t settings_hd_table_bufsize_max);
/*
* Changes header table size in the |inflater|. This may trigger
* eviction in the dynamic table.
*
* The |settings_hd_table_bufsize_max| should be the value transmitted
* in SETTINGS_HEADER_TABLE_SIZE.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
size_t settings_hd_table_bufsize_max);
/* /*
* Deflates the |nva|, which has the |nvlen| name/value pairs, into * Deflates the |nva|, which has the |nvlen| name/value pairs, into
* the |bufs|. * the |bufs|.
@ -322,54 +289,21 @@ int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
nghttp2_bufs *bufs, nghttp2_bufs *bufs,
nghttp2_nv *nva, size_t nvlen); nghttp2_nv *nva, size_t nvlen);
typedef enum {
NGHTTP2_HD_INFLATE_NONE = 0,
NGHTTP2_HD_INFLATE_FINAL = 1,
NGHTTP2_HD_INFLATE_EMIT = (1 << 1)
} nghttp2_hd_inflate_flag;
/* /*
* Inflates name/value block stored in |in| with length |inlen|. This * Initializes |inflater| for inflating name/values pairs.
* function performs decompression. For each successful emission of
* header name/value pair, NGHTTP2_HD_INFLATE_EMIT is set in
* |*inflate_flags| and name/value pair is assigned to the |nv_out|
* and the function returns. The caller must not free the members of
* |nv_out|.
* *
* The |nv_out| may include pointers to the memory region in the * This function returns 0 if it succeeds, or one of the following
* |in|. The caller must retain the |in| while the |nv_out| is used. * negative error codes:
* *
* The application should call this function repeatedly until the * :enum:`NGHTTP2_ERR_NOMEM`
* |(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL| is nonzero and return
* value is non-negative. This means the all input values are
* processed successfully. Then the application must call
* `nghttp2_hd_inflate_end_headers()` to prepare for the next header
* block input.
*
* The caller can feed complete compressed header block. It also can
* feed it in several chunks. The caller must set |in_final| to
* nonzero if the given input is the last block of the compressed
* header.
*
* This function returns the number of bytes processed if it succeeds,
* or one of the following negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_HEADER_COMP
* Inflation process has failed.
*/ */
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater);
nghttp2_nv *nv_out, int *inflate_flags,
uint8_t *in, size_t inlen, int in_final);
/* /*
* Signals the end of decompression for one header block. * Deallocates any resources allocated for |inflater|.
*
* This function returns 0 if it succeeds. Currently this function
* always succeeds.
*/ */
int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater); void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
/* For unittesting purpose */ /* For unittesting purpose */
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index, int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,