2014-01-05 15:50:12 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# This script reads input headers from json file given in the
|
|
|
|
# command-line (each file must be written in the format described in
|
|
|
|
# https://github.com/Jxck/hpack-test-case but we require only
|
|
|
|
# 'headers' data). Then it encodes input header set and write the
|
|
|
|
# encoded header block in the same format. The output files are
|
|
|
|
# created under 'out' directory in the current directory. It must
|
|
|
|
# exist, otherwise the script will fail. The output filename is the
|
|
|
|
# same as the input filename.
|
|
|
|
#
|
2014-01-21 13:50:01 +01:00
|
|
|
import sys, base64, json, os.path, os, argparse, errno
|
2014-01-05 15:50:12 +01:00
|
|
|
from binascii import b2a_hex
|
|
|
|
import nghttp2
|
|
|
|
|
2014-01-21 15:04:31 +01:00
|
|
|
def testsuite(testdata, filename, outdir, table_size, deflate_table_size):
|
2014-01-05 15:50:12 +01:00
|
|
|
if testdata['context'] == 'request':
|
|
|
|
side = nghttp2.HD_SIDE_REQUEST
|
|
|
|
else:
|
|
|
|
side = nghttp2.HD_SIDE_RESPONSE
|
|
|
|
|
|
|
|
res = {
|
|
|
|
'draft':5, 'context': testdata['context'],
|
|
|
|
'description': '''\
|
|
|
|
Encoded by nghttp2. The basic encoding strategy is described in \
|
|
|
|
http://lists.w3.org/Archives/Public/ietf-http-wg/2013JulSep/1135.html \
|
|
|
|
We use huffman encoding only if it produces strictly shorter byte string than \
|
|
|
|
original. We make some headers not indexing at all, but this does not always \
|
|
|
|
result in less bits on the wire.'''
|
|
|
|
}
|
|
|
|
cases = []
|
2014-01-21 15:04:31 +01:00
|
|
|
deflater = nghttp2.HDDeflater(side, deflate_table_size)
|
2014-01-21 13:50:01 +01:00
|
|
|
deflater.change_table_size(table_size)
|
2014-01-05 15:50:12 +01:00
|
|
|
for casenum, item in enumerate(testdata['cases']):
|
|
|
|
outitem = {
|
2014-01-21 13:50:01 +01:00
|
|
|
'header_table_size': table_size,
|
2014-01-05 15:50:12 +01:00
|
|
|
'headers': item['headers']
|
|
|
|
}
|
|
|
|
casenum += 1
|
|
|
|
hdrs = [(list(x.keys())[0].encode('utf-8'),
|
|
|
|
list(x.values())[0].encode('utf-8')) \
|
|
|
|
for x in item['headers']]
|
|
|
|
outitem['wire'] = b2a_hex(deflater.deflate(hdrs)).decode('utf-8')
|
|
|
|
cases.append(outitem)
|
|
|
|
res['cases'] = cases
|
|
|
|
jsonstr = json.dumps(res, indent=2)
|
2014-01-21 13:50:01 +01:00
|
|
|
with open(os.path.join(outdir, filename), 'w') as f:
|
2014-01-05 15:50:12 +01:00
|
|
|
f.write(jsonstr)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2014-01-21 13:50:01 +01:00
|
|
|
ap = argparse.ArgumentParser(description='HPACK test case generator')
|
|
|
|
ap.add_argument('-d', '--dir', help='output directory', default='out')
|
|
|
|
ap.add_argument('-s', '--table-size', help='max header table size',
|
|
|
|
type=int, default=4096)
|
2014-01-21 15:04:31 +01:00
|
|
|
ap.add_argument('-S', '--deflate-table-size',
|
|
|
|
help='max header table size for deflater',
|
|
|
|
type=int, default=4096)
|
2014-01-21 13:50:01 +01:00
|
|
|
ap.add_argument('file', nargs='*', help='input file')
|
|
|
|
args = ap.parse_args()
|
|
|
|
try:
|
|
|
|
os.mkdir(args.dir)
|
|
|
|
except OSError as e:
|
|
|
|
if e.errno != errno.EEXIST:
|
|
|
|
raise e
|
|
|
|
for filename in args.file:
|
2014-01-05 15:50:12 +01:00
|
|
|
sys.stderr.write('{}\n'.format(filename))
|
|
|
|
with open(filename) as f:
|
|
|
|
input = f.read()
|
2014-01-21 13:50:01 +01:00
|
|
|
testsuite(json.loads(input), os.path.basename(filename),
|
2014-01-21 15:04:31 +01:00
|
|
|
args.dir, args.table_size, args.deflate_table_size)
|