From bddfa3c0b6a453e3ef14477c11b314b440d6db68 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 18 Dec 2013 00:20:14 +0900 Subject: [PATCH] python: Add method to get/print header table --- python/cnghttp2.pxd | 15 ++++++++++++++- python/nghttp2.pyx | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/python/cnghttp2.pxd b/python/cnghttp2.pxd index 8846457e..a35ce3ab 100644 --- a/python/cnghttp2.pxd +++ b/python/cnghttp2.pxd @@ -42,12 +42,22 @@ cdef extern from 'nghttp2_frame.h': cdef extern from 'nghttp2_hd.h': + # This is macro + int NGHTTP2_HD_ENTRY_OVERHEAD + ctypedef enum nghttp2_hd_side: NGHTTP2_HD_SIDE_REQUEST 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: - pass + size_t deflate_hd_tablelen int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater, nghttp2_hd_side side, @@ -77,3 +87,6 @@ cdef extern from 'nghttp2_hd.h': uint8_t *input, size_t inlen) 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) diff --git a/python/nghttp2.pyx b/python/nghttp2.pyx index 751b78d8..20eed0fc 100644 --- a/python/nghttp2.pyx +++ b/python/nghttp2.pyx @@ -31,6 +31,18 @@ HD_SIDE_RESPONSE = cnghttp2.NGHTTP2_HD_SIDE_RESPONSE 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 cnghttp2.nghttp2_hd_context _ctx @@ -50,6 +62,18 @@ cdef class _HDContextBase: if rv != 0: 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): '''Performs header compression. The header compression algorithm has 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): 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')))