Return NGHTTP2_ERR_BUFFER_ERROR from nghttp2_hd_{deflate,inflate}_hd

It is generally useful to know what is the cause of the error.  Since
we expose HPACK API, it is friendly to tell application the
insufficient buffer size is a culprit.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-05-12 21:48:00 +09:00
parent bc6d952361
commit ab76468971
6 changed files with 30 additions and 22 deletions

View File

@ -200,6 +200,10 @@ typedef enum {
* Invalid argument passed. * Invalid argument passed.
*/ */
NGHTTP2_ERR_INVALID_ARGUMENT = -501, NGHTTP2_ERR_INVALID_ARGUMENT = -501,
/**
* Ouf of buffer space.
*/
NGHTTP2_ERR_BUFFER_ERROR = -502,
/** /**
* The specified protocol version is not supported. * The specified protocol version is not supported.
*/ */
@ -2811,6 +2815,8 @@ typedef enum {
* Out of memory. * Out of memory.
* :enum:`NGHTTP2_ERR_HEADER_COMP` * :enum:`NGHTTP2_ERR_HEADER_COMP`
* Inflation process has failed. * Inflation process has failed.
* :enum:`NGHTTP2_ERR_BUFFER_ERROR`
* The heder field name or value is too large.
* *
* Example follows:: * Example follows::
* *

View File

@ -366,6 +366,10 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs,
/* This call will adjust buf->last to the correct position */ /* This call will adjust buf->last to the correct position */
rv = nghttp2_hd_deflate_hd(deflater, bufs, frame->nva, frame->nvlen); rv = nghttp2_hd_deflate_hd(deflater, bufs, frame->nva, frame->nvlen);
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
rv = NGHTTP2_ERR_HEADER_COMP;
}
buf->pos -= nv_offset; buf->pos -= nv_offset;
if(rv != 0) { if(rv != 0) {
@ -593,6 +597,10 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
/* This call will adjust buf->last to the correct position */ /* This call will adjust buf->last to the correct position */
rv = nghttp2_hd_deflate_hd(deflater, bufs, frame->nva, frame->nvlen); rv = nghttp2_hd_deflate_hd(deflater, bufs, frame->nva, frame->nvlen);
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
rv = NGHTTP2_ERR_HEADER_COMP;
}
buf->pos -= nv_offset; buf->pos -= nv_offset;
if(rv != 0) { if(rv != 0) {

View File

@ -559,14 +559,6 @@ static uint8_t* decode_length(ssize_t *res, int *final, ssize_t initial,
return in + 1; return in + 1;
} }
static int hd_handle_buffer_error(int rv)
{
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
return NGHTTP2_ERR_HEADER_COMP;
}
return rv;
}
static int emit_clear_refset(nghttp2_bufs *bufs) static int emit_clear_refset(nghttp2_bufs *bufs)
{ {
int rv; int rv;
@ -575,7 +567,7 @@ static int emit_clear_refset(nghttp2_bufs *bufs)
rv = nghttp2_bufs_addb(bufs, 0x30u); rv = nghttp2_bufs_addb(bufs, 0x30u);
if(rv != 0) { if(rv != 0) {
return hd_handle_buffer_error(rv); return rv;
} }
return 0; return 0;
@ -604,7 +596,7 @@ static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
rv = nghttp2_bufs_add(bufs, sb, blocklen); rv = nghttp2_bufs_add(bufs, sb, blocklen);
if(rv != 0) { if(rv != 0) {
return hd_handle_buffer_error(rv); return rv;
} }
return 0; return 0;
@ -632,7 +624,7 @@ static int emit_indexed_block(nghttp2_bufs *bufs, size_t index)
rv = nghttp2_bufs_add(bufs, sb, blocklen); rv = nghttp2_bufs_add(bufs, sb, blocklen);
if(rv != 0) { if(rv != 0) {
return hd_handle_buffer_error(rv); return rv;
} }
return 0; return 0;
@ -665,7 +657,7 @@ static int emit_string(nghttp2_bufs *bufs,
rv = nghttp2_bufs_add(bufs, sb, blocklen); rv = nghttp2_bufs_add(bufs, sb, blocklen);
if(rv != 0) { if(rv != 0) {
return hd_handle_buffer_error(rv); return rv;
} }
if(huffman) { if(huffman) {
@ -675,7 +667,7 @@ static int emit_string(nghttp2_bufs *bufs,
rv = nghttp2_bufs_add(bufs, str, len); rv = nghttp2_bufs_add(bufs, str, len);
} }
return hd_handle_buffer_error(rv); return rv;
} }
static uint8_t pack_first_byte(int inc_indexing, int no_index) static uint8_t pack_first_byte(int inc_indexing, int no_index)
@ -737,7 +729,7 @@ static int emit_indname_block(nghttp2_bufs *bufs, size_t index,
rv = nghttp2_bufs_add(bufs, sb, blocklen); rv = nghttp2_bufs_add(bufs, sb, blocklen);
if(rv != 0) { if(rv != 0) {
return hd_handle_buffer_error(rv); return rv;
} }
rv = emit_string(bufs, encvallen, huffman, nv->value, nv->valuelen); rv = emit_string(bufs, encvallen, huffman, nv->value, nv->valuelen);
@ -779,7 +771,7 @@ static int emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
rv = nghttp2_bufs_addb(bufs, pack_first_byte(inc_indexing, no_index)); rv = nghttp2_bufs_addb(bufs, pack_first_byte(inc_indexing, no_index));
if(rv != 0) { if(rv != 0) {
return hd_handle_buffer_error(rv); return rv;
} }
rv = emit_string(bufs, encnamelen, name_huffman, nv->name, nv->namelen); rv = emit_string(bufs, encnamelen, name_huffman, nv->name, nv->namelen);
@ -1319,6 +1311,8 @@ static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater,
* Out of memory * Out of memory
* NGHTTP2_ERR_HEADER_COMP * NGHTTP2_ERR_HEADER_COMP
* Huffman decoding failed * Huffman decoding failed
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/ */
static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater, static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
nghttp2_bufs *bufs, nghttp2_bufs *bufs,
@ -1332,9 +1326,7 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
} }
rv = nghttp2_hd_huff_decode(&inflater->huff_decode_ctx, bufs, rv = nghttp2_hd_huff_decode(&inflater->huff_decode_ctx, bufs,
in, last - in, final); in, last - in, final);
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
return NGHTTP2_ERR_HEADER_COMP;
}
if(rv < 0) { if(rv < 0) {
DEBUGF(fprintf(stderr, "inflatehd: huffman decoding failed\n")); DEBUGF(fprintf(stderr, "inflatehd: huffman decoding failed\n"));
return rv; return rv;
@ -1354,6 +1346,8 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
* Out of memory * Out of memory
* NGHTTP2_ERR_HEADER_COMP * NGHTTP2_ERR_HEADER_COMP
* Header decompression failed * Header decompression failed
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/ */
static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater, static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater,
nghttp2_bufs *bufs, nghttp2_bufs *bufs,
@ -1362,9 +1356,6 @@ static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater,
int rv; int rv;
size_t len = nghttp2_min(last - in, inflater->left); size_t len = nghttp2_min(last - in, inflater->left);
rv = nghttp2_bufs_add(bufs, in, len); rv = nghttp2_bufs_add(bufs, in, len);
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
return NGHTTP2_ERR_HEADER_COMP;
}
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }

View File

@ -286,6 +286,8 @@ int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
* Out of memory. * Out of memory.
* NGHTTP2_ERR_HEADER_COMP * NGHTTP2_ERR_HEADER_COMP
* Deflation process has failed. * Deflation process has failed.
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/ */
int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
nghttp2_bufs *bufs, nghttp2_bufs *bufs,

View File

@ -167,6 +167,8 @@ const char* nghttp2_strerror(int error_code)
return "Success"; return "Success";
case NGHTTP2_ERR_INVALID_ARGUMENT: case NGHTTP2_ERR_INVALID_ARGUMENT:
return "Invalid argument"; return "Invalid argument";
case NGHTTP2_ERR_BUFFER_ERROR:
return "Out of buffer space";
case NGHTTP2_ERR_UNSUPPORTED_VERSION: case NGHTTP2_ERR_UNSUPPORTED_VERSION:
return "Unsupported SPDY version"; return "Unsupported SPDY version";
case NGHTTP2_ERR_WOULDBLOCK: case NGHTTP2_ERR_WOULDBLOCK:

View File

@ -45,7 +45,6 @@ typedef int (*nghttp2_compar)(const void *lhs, const void *rhs);
inclusive. */ inclusive. */
typedef enum { typedef enum {
NGHTTP2_ERR_CREDENTIAL_PENDING = -101, NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
NGHTTP2_ERR_BUFFER_ERROR = -102,
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103, NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
NGHTTP2_ERR_IGN_PAYLOAD = -104 NGHTTP2_ERR_IGN_PAYLOAD = -104
} nghttp2_internal_error; } nghttp2_internal_error;