python: Add method to get/print header table

This commit is contained in:
Tatsuhiro Tsujikawa 2013-12-18 00:20:14 +09:00
parent 415b9d07d8
commit bddfa3c0b6
2 changed files with 55 additions and 1 deletions

View File

@ -42,12 +42,22 @@ cdef extern from 'nghttp2_frame.h':
cdef extern from 'nghttp2_hd.h': cdef extern from 'nghttp2_hd.h':
# This is macro
int NGHTTP2_HD_ENTRY_OVERHEAD
ctypedef enum nghttp2_hd_side: ctypedef enum nghttp2_hd_side:
NGHTTP2_HD_SIDE_REQUEST NGHTTP2_HD_SIDE_REQUEST
NGHTTP2_HD_SIDE_RESPONSE NGHTTP2_HD_SIDE_RESPONSE
ctypedef enum nghttp2_hd_flags:
NGHTTP2_HD_FLAG_REFSET
ctypedef struct nghttp2_hd_entry:
nghttp2_nv nv
uint8_t flags
ctypedef struct nghttp2_hd_context: ctypedef struct nghttp2_hd_context:
pass size_t deflate_hd_tablelen
int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater, int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater,
nghttp2_hd_side side, nghttp2_hd_side side,
@ -77,3 +87,6 @@ cdef extern from 'nghttp2_hd.h':
uint8_t *input, size_t inlen) uint8_t *input, size_t inlen)
int nghttp2_hd_end_headers(nghttp2_hd_context *deflater_or_inflater) int nghttp2_hd_end_headers(nghttp2_hd_context *deflater_or_inflater)
nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
size_t index)

View File

@ -31,6 +31,18 @@ HD_SIDE_RESPONSE = cnghttp2.NGHTTP2_HD_SIDE_RESPONSE
HD_DEFLATE_HD_TABLE_BUFSIZE_MAX = 4096 HD_DEFLATE_HD_TABLE_BUFSIZE_MAX = 4096
HD_ENTRY_OVERHEAD = cnghttp2.NGHTTP2_HD_ENTRY_OVERHEAD
class HDTableEntry:
def __init__(self, name, value, ref):
self.name = name
self.value = value
self.ref = ref
def space(self):
return len(self.name) + len(self.value) + HD_ENTRY_OVERHEAD
cdef class _HDContextBase: cdef class _HDContextBase:
cdef cnghttp2.nghttp2_hd_context _ctx cdef cnghttp2.nghttp2_hd_context _ctx
@ -50,6 +62,18 @@ cdef class _HDContextBase:
if rv != 0: if rv != 0:
raise Exception(_strerror(rv)) raise Exception(_strerror(rv))
def get_hd_table(self):
'''Returns copy of current dynamic header table.'''
cdef int length = self._ctx.deflate_hd_tablelen
cdef cnghttp2.nghttp2_hd_entry *entry
res = []
for i in range(length):
entry = cnghttp2.nghttp2_hd_table_get(&self._ctx, i)
res.append(HDTableEntry(entry.nv.name[:entry.nv.namelen],
entry.nv.value[:entry.nv.valuelen],
(entry.flags & cnghttp2.NGHTTP2_HD_FLAG_REFSET) != 0))
return res
cdef class HDDeflater(_HDContextBase): cdef class HDDeflater(_HDContextBase):
'''Performs header compression. The header compression algorithm has '''Performs header compression. The header compression algorithm has
to know the header set to be compressed is request headers or to know the header set to be compressed is request headers or
@ -178,3 +202,20 @@ cdef class HDInflater(_HDContextBase):
cdef _strerror(int liberror_code): cdef _strerror(int liberror_code):
return cnghttp2.nghttp2_strerror(liberror_code).decode('utf-8') return cnghttp2.nghttp2_strerror(liberror_code).decode('utf-8')
def print_hd_table(hdtable):
'''Convenient function to print |hdtable| to the standard output. This
function does not work if header name/value cannot be decoded using
UTF-8 encoding.
s=N means the entry occupies N bytes in header table. if r=y, then
the entry is in the reference set.
'''
idx = 0
for entry in hdtable:
idx += 1
print('[{}] (s={}) (r={}) {}: {}'.format(idx, entry.space(),
'y' if entry.ref else 'n',
entry.name.decode('utf-8'),
entry.value.decode('utf-8')))