hdtest: Add header dump with -d option

This commit is contained in:
Tatsuhiro Tsujikawa 2013-10-27 01:04:42 +09:00
parent 495788dff1
commit f8f32125d9
5 changed files with 152 additions and 23 deletions

View File

@ -31,9 +31,11 @@ LDADD = $(top_builddir)/lib/libnghttp2.la
bin_PROGRAMS = inflatehd deflatehd bin_PROGRAMS = inflatehd deflatehd
inflatehd_SOURCES = inflatehd.c COMMON_SRCS = comp_helper.c comp_helper.h
deflatehd_SOURCES = deflatehd.c inflatehd_SOURCES = inflatehd.c $(COMMON_SRCS)
deflatehd_SOURCES = deflatehd.c $(COMMON_SRCS)
endif # ENABLE_HDTEST endif # ENABLE_HDTEST

67
hdtest/comp_helper.c Normal file
View File

@ -0,0 +1,67 @@
/*
* nghttp2 - HTTP/2.0 C Library
*
* Copyright (c) 2013 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "comp_helper.h"
void dump_val(json_t *jent, const char *key, uint8_t *val, size_t len)
{
if(val == NULL) {
json_object_set_new(jent, key, json_string("**DEALLOCATED**"));
} else {
json_object_set_new(jent, key, json_pack("s#", val, len));
}
}
json_t* dump_header_table(nghttp2_hd_context *context)
{
json_t *obj, *entries;
size_t i;
obj = json_object();
entries = json_array();
for(i = 0; i < context->hd_table.len; ++i) {
nghttp2_hd_entry *ent = nghttp2_hd_table_get(context, i);
json_t *outent = json_object();
json_object_set_new(outent, "index", json_integer(i));
dump_val(outent, "name", ent->nv.name, ent->nv.namelen);
dump_val(outent, "value", ent->nv.value, ent->nv.valuelen);
json_object_set_new(outent, "referenced",
json_boolean(ent->flags & NGHTTP2_HD_FLAG_REFSET));
json_object_set_new(outent, "size",
json_integer(ent->nv.namelen + ent->nv.valuelen +
NGHTTP2_HD_ENTRY_OVERHEAD));
json_array_append_new(entries, outent);
}
json_object_set_new(obj, "entries", entries);
json_object_set_new(obj, "size", json_integer(context->hd_table_bufsize));
json_object_set_new(obj, "maxSize",
json_integer(context->hd_table_bufsize_max));
if(context->role == NGHTTP2_HD_ROLE_DEFLATE) {
json_object_set_new(obj, "localSize",
json_integer(context->local_hd_table_bufsize));
json_object_set_new(obj, "localMaxSize",
json_integer(context->local_hd_table_bufsize_max));
}
return obj;
}

38
hdtest/comp_helper.h Normal file
View File

@ -0,0 +1,38 @@
/*
* nghttp2 - HTTP/2.0 C Library
*
* Copyright (c) 2013 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef NGHTTP2_COMP_HELPER_H
#define NGHTTP2_COMP_HELPER_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <jansson.h>
#include "nghttp2_hd.h"
json_t* dump_header_table(nghttp2_hd_context *context);
#endif /* NGHTTP2_COMP_HELPER_H */

View File

@ -11,11 +11,14 @@
#include "nghttp2_hd.h" #include "nghttp2_hd.h"
#include "nghttp2_frame.h" #include "nghttp2_frame.h"
#include "comp_helper.h"
typedef struct { typedef struct {
nghttp2_hd_side side; nghttp2_hd_side side;
size_t table_size; size_t table_size;
size_t local_table_size; size_t local_table_size;
int http1text; int http1text;
int dump_header_table;
} deflate_config; } deflate_config;
static deflate_config config; static deflate_config config;
@ -29,7 +32,8 @@ static void to_hex(char *dest, const uint8_t *src, size_t len)
} }
} }
static void output_to_json(const uint8_t *buf, size_t len, size_t inputlen, static void output_to_json(nghttp2_hd_context *deflater,
const uint8_t *buf, size_t len, size_t inputlen,
int seq) int seq)
{ {
json_t *obj; json_t *obj;
@ -47,7 +51,10 @@ static void output_to_json(const uint8_t *buf, size_t len, size_t inputlen,
json_real((double)len / inputlen * 100)); json_real((double)len / inputlen * 100));
to_hex(hex, buf, len); to_hex(hex, buf, len);
json_object_set_new(obj, "output", json_pack("s#", hex, len * 2)); json_object_set_new(obj, "output", json_pack("s#", hex, len * 2));
json_dumpf(obj, stdout, JSON_PRESERVE_ORDER); if(config.dump_header_table) {
json_object_set_new(obj, "headerTable", dump_header_table(deflater));
}
json_dumpf(obj, stdout, JSON_PRESERVE_ORDER | JSON_INDENT(2));
printf("\n"); printf("\n");
json_decref(obj); json_decref(obj);
} }
@ -63,7 +70,7 @@ static void deflate_hd(nghttp2_hd_context *deflater,
fprintf(stderr, "deflate failed with error code %zd at %d\n", rv, seq); fprintf(stderr, "deflate failed with error code %zd at %d\n", rv, seq);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
output_to_json(buf, rv, inputlen, seq); output_to_json(deflater, buf, rv, inputlen, seq);
nghttp2_hd_end_headers(deflater); nghttp2_hd_end_headers(deflater);
free(buf); free(buf);
} }
@ -260,21 +267,16 @@ static void print_help(void)
" Each header set is delimited by single empty\n" " Each header set is delimited by single empty\n"
" line.\n" " line.\n"
" -s, --table-size=<N>\n" " -s, --table-size=<N>\n"
" Set dynamic table size. This value is the\n" " Set dynamic table size. In the HPACK\n"
" buffer size the decoder uses. In the HPACK\n"
" specification, this value is denoted by\n" " specification, this value is denoted by\n"
" SETTINGS_HEADER_TABLE_SIZE.\n" " SETTINGS_HEADER_TABLE_SIZE.\n"
" Default: 4096\n" " Default: 4096\n"
" -S, --local-table-size=<N>\n" " -S, --local-table-size=<N>\n"
" Set effective dynamic table size when\n" " Use first N bytes of dynamic header table\n"
" encoding headers. Although a decoder uses\n" " buffer.\n"
" the value specified in -s option, encoder\n" " Default: 4096\n"
" can use smaller buffer size than that. This\n" " -d, --dump-header-table\n"
" option specifies it. Therefore it is\n" " Output dynamic header table.\n");
" meaningless to specify the value equals to\n"
" or greater than the value given in -s\n"
" option.\n"
" Default: 4096\n");
} }
static struct option long_options[] = { static struct option long_options[] = {
@ -282,6 +284,7 @@ static struct option long_options[] = {
{"http1text", no_argument, NULL, 't'}, {"http1text", no_argument, NULL, 't'},
{"table-size", required_argument, NULL, 's'}, {"table-size", required_argument, NULL, 's'},
{"local-table-size", required_argument, NULL, 'S'}, {"local-table-size", required_argument, NULL, 'S'},
{"dump-header-table", no_argument, NULL, 'd'},
{NULL, 0, NULL, 0 } {NULL, 0, NULL, 0 }
}; };
@ -294,9 +297,10 @@ int main(int argc, char **argv)
config.table_size = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; config.table_size = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
config.local_table_size = NGHTTP2_HD_DEFAULT_LOCAL_MAX_BUFFER_SIZE; config.local_table_size = NGHTTP2_HD_DEFAULT_LOCAL_MAX_BUFFER_SIZE;
config.http1text = 0; config.http1text = 0;
config.dump_header_table = 0;
while(1) { while(1) {
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "S:hrs:t", long_options, &option_index); int c = getopt_long(argc, argv, "S:dhrs:t", long_options, &option_index);
if(c == -1) { if(c == -1) {
break; break;
} }
@ -328,6 +332,10 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; break;
case 'd':
/* --dump-header-table */
config.dump_header_table = 1;
break;
case '?': case '?':
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default:

View File

@ -11,9 +11,12 @@
#include "nghttp2_hd.h" #include "nghttp2_hd.h"
#include "nghttp2_frame.h" #include "nghttp2_frame.h"
#include "comp_helper.h"
typedef struct { typedef struct {
nghttp2_hd_side side; nghttp2_hd_side side;
size_t table_size; size_t table_size;
int dump_header_table;
} inflate_config; } inflate_config;
static inflate_config config; static inflate_config config;
@ -37,7 +40,8 @@ static void decode_hex(uint8_t *dest, const char *src, size_t len)
} }
} }
static void nva_to_json(const nghttp2_nv *nva, size_t nvlen, int seq) static void nva_to_json(nghttp2_hd_context *inflater,
const nghttp2_nv *nva, size_t nvlen, int seq)
{ {
size_t i; size_t i;
json_t *obj; json_t *obj;
@ -53,6 +57,9 @@ static void nva_to_json(const nghttp2_nv *nva, size_t nvlen, int seq)
json_array_append_new(nv_pair, json_pack("s#", nv->value, nv->valuelen)); json_array_append_new(nv_pair, json_pack("s#", nv->value, nv->valuelen));
json_array_append_new(headers, nv_pair); json_array_append_new(headers, nv_pair);
} }
if(config.dump_header_table) {
json_object_set_new(obj, "headerTable", dump_header_table(inflater));
}
json_dumpf(obj, stdout, JSON_INDENT(2) | JSON_PRESERVE_ORDER); json_dumpf(obj, stdout, JSON_INDENT(2) | JSON_PRESERVE_ORDER);
json_decref(obj); json_decref(obj);
printf("\n"); printf("\n");
@ -88,7 +95,7 @@ static int inflate_hd(json_t *obj, nghttp2_hd_context *inflater, int seq)
resnvlen, seq); resnvlen, seq);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
nva_to_json(resnva, resnvlen, seq); nva_to_json(inflater, resnva, resnvlen, seq);
nghttp2_hd_end_headers(inflater); nghttp2_hd_end_headers(inflater);
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
return 0; return 0;
@ -155,16 +162,18 @@ static void print_help(void)
" -r, --response Use response compression context instead of\n" " -r, --response Use response compression context instead of\n"
" request.\n" " request.\n"
" -s, --table-size=<N>\n" " -s, --table-size=<N>\n"
" Set dynamic table size. This value is the\n" " Set dynamic table size. In the HPACK\n"
" buffer size the decoder uses. In the HPACK\n"
" specification, this value is denoted by\n" " specification, this value is denoted by\n"
" SETTINGS_HEADER_TABLE_SIZE.\n" " SETTINGS_HEADER_TABLE_SIZE.\n"
" Default: 4096\n"); " Default: 4096\n"
" -d, --dump-header-table\n"
" Output dynamic header table.\n");
} }
static struct option long_options[] = { static struct option long_options[] = {
{"response", no_argument, NULL, 'r'}, {"response", no_argument, NULL, 'r'},
{"table-size", required_argument, NULL, 's'}, {"table-size", required_argument, NULL, 's'},
{"dump-header-table", no_argument, NULL, 'd'},
{NULL, 0, NULL, 0 } {NULL, 0, NULL, 0 }
}; };
@ -173,9 +182,10 @@ int main(int argc, char **argv)
char *end; char *end;
config.side = NGHTTP2_HD_SIDE_REQUEST; config.side = NGHTTP2_HD_SIDE_REQUEST;
config.table_size = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; config.table_size = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
config.dump_header_table = 0;
while(1) { while(1) {
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "hrs:", long_options, &option_index); int c = getopt_long(argc, argv, "dhrs:", long_options, &option_index);
if(c == -1) { if(c == -1) {
break; break;
} }
@ -195,6 +205,10 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; break;
case 'd':
/* --dump-header-table */
config.dump_header_table = 1;
break;
case '?': case '?':
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default: