hdtest: Add header dump with -d option
This commit is contained in:
parent
495788dff1
commit
f8f32125d9
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue