diff --git a/python/spdyclient.py b/python/spdyclient.py index 6065ee47..c767e1e5 100644 --- a/python/spdyclient.py +++ b/python/spdyclient.py @@ -65,8 +65,8 @@ def on_ctrl_recv_cb(session, frame): if req.decomp: return for k, v in frame.nv: - if k == b'content-encoding' and \ - (v.lower() == b'gzip' or v.lower() == b'deflate'): + if k == 'content-encoding' and \ + (v.lower() == 'gzip' or v.lower() == 'deflate'): req.decomp = zlib.decompressobj() def on_data_chunk_recv_cb(session, flags, stream_id, data): @@ -148,13 +148,13 @@ def get(uri): if uricomps.query: path = '?'.join([path, uricomps.query]) - session.submit_request(0, [(b':method', b'GET'), - (b':scheme', b'https'), - (b':path', path.encode('utf-8')), - (b':version', b'HTTP/1.1'), - (b':host', hostport.encode('utf-8')), - (b'accept', b'*/*'), - (b'user-agent', b'python-spdylay')], + session.submit_request(0, [(':method', 'GET'), + (':scheme', 'https'), + (':path', path), + (':version', 'HTTP/1.1'), + (':host', hostport), + ('accept', '*/*'), + ('user-agent', 'python-spdylay')], stream_user_data=req) while (session.want_read() or session.want_write()) \ diff --git a/python/spdylay.pyx b/python/spdylay.pyx index 529c1a33..2c758552 100644 --- a/python/spdylay.pyx +++ b/python/spdylay.pyx @@ -206,17 +206,18 @@ cdef class WindowUpdateFrame(CtrlFrame): cdef object cnv2pynv(char **nv): ''' Convert C-style name/value pairs ``nv`` to Python style - pairs. ''' + pairs. We assume that strings in nv is UTF-8 encoded as per SPDY + spec. In Python pairs, we use unicode string.''' cdef size_t i pynv = [] i = 0 while nv[i] != NULL: - pynv.append((nv[i], nv[i+1])) + pynv.append((nv[i].decode('UTF-8'), nv[i+1].decode('UTF-8'))) i += 2 return pynv cdef char** pynv2cnv(object nv) except *: - ''' Convert Python style name/value pairs ``nv`` to C-style + ''' Convert Python style UTF-8 name/value pairs ``nv`` to C-style pairs. Python style name/value pairs are list of tuple (key, value).''' cdef char **cnv = malloc((len(nv)*2+1)*sizeof(char*)) @@ -232,6 +233,12 @@ cdef char** pynv2cnv(object nv) except *: cnv[i] = NULL return cnv +cdef pynv_encode(nv): + res = [] + for k, v in nv: + res.append((k.encode('UTF-8'), v.encode('UTF-8'))) + return res + cdef object csettings2pysettings(size_t niv, cspdylay.spdylay_settings_entry *iv): cdef size_t i = 0 @@ -804,8 +811,10 @@ cdef class Session: cpdef submit_request(self, pri, nv, data_prd=None, stream_user_data=None): cdef cspdylay.spdylay_data_provider c_data_prd cdef cspdylay.spdylay_data_provider *c_data_prd_ptr - cdef char **cnv = pynv2cnv(nv) cpdef int rv + cdef char **cnv + nv = pynv_encode(nv) + cnv = pynv2cnv(nv) if data_prd: create_c_data_prd(&c_data_prd, data_prd) c_data_prd_ptr = &c_data_prd @@ -826,8 +835,10 @@ cdef class Session: cpdef submit_response(self, stream_id, nv, data_prd=None): cdef cspdylay.spdylay_data_provider c_data_prd cdef cspdylay.spdylay_data_provider *c_data_prd_ptr - cdef char **cnv = pynv2cnv(nv) cpdef int rv + cdef char **cnv + nv = pynv_encode(nv) + cnv = pynv2cnv(nv) if data_prd: create_c_data_prd(&c_data_prd, data_prd) c_data_prd_ptr = &c_data_prd @@ -846,8 +857,10 @@ cdef class Session: cpdef submit_syn_stream(self, flags, assoc_stream_id, pri, nv, stream_user_data): - cdef char **cnv = pynv2cnv(nv) cdef int rv + cdef char **cnv + nv = pynv_encode(nv) + cnv = pynv2cnv(nv) rv = cspdylay.spdylay_submit_syn_stream(self._c_session, flags, assoc_stream_id, @@ -863,8 +876,10 @@ cdef class Session: raise MemoryError() cpdef submit_syn_reply(self, flags, stream_id, nv): - cdef char **cnv = pynv2cnv(nv) cdef int rv + cdef char **cnv + nv = pynv_encode(nv) + cnv = pynv2cnv(nv) rv = cspdylay.spdylay_submit_syn_reply(self._c_session, flags, stream_id, cnv) free(cnv) @@ -876,8 +891,10 @@ cdef class Session: raise MemoryError() cpdef submit_headers(self, flags, stream_id, nv): - cdef char **cnv = pynv2cnv(nv) cdef int rv + cdef char **cnv + nv = pynv_encode(nv) + cnv = pynv2cnv(nv) rv = cspdylay.spdylay_submit_headers(self._c_session, flags, stream_id, cnv) free(cnv) diff --git a/python/spdylay_tests.py b/python/spdylay_tests.py index 11b8c8cf..cce51e3b 100644 --- a/python/spdylay_tests.py +++ b/python/spdylay_tests.py @@ -88,7 +88,7 @@ class SpdylayTests(unittest.TestCase): def test_submit_request_and_response(self): data_prd = spdylay.DataProvider(io.BytesIO(b'Hello World'), read_cb) - self.client_session.submit_request(0, [(b':method', b'POST')], + self.client_session.submit_request(0, [(u':method', u'POST')], data_prd=data_prd, stream_user_data=data_prd) self.client_session.send() @@ -100,7 +100,7 @@ class SpdylayTests(unittest.TestCase): self.assertEqual(1, frame.stream_id) self.assertEqual(0, frame.assoc_stream_id) self.assertEqual(0, frame.pri) - self.assertEqual((b':method', b'POST'), frame.nv[0]) + self.assertEqual((u':method', u'POST'), frame.nv[0]) self.assertEqual(b'Hello World', self.server_streams.recv_data.getvalue()) @@ -108,7 +108,7 @@ class SpdylayTests(unittest.TestCase): self.assertEqual(data_prd, self.client_session.get_stream_user_data(1)) data_prd = spdylay.DataProvider(io.BytesIO(b'Foo the bar'), read_cb) - self.server_session.submit_response(1, [(b':status', b'200 OK')], + self.server_session.submit_response(1, [(u':status', u'200 OK')], data_prd=data_prd) self.server_session.send() self.client_session.recv() @@ -117,14 +117,14 @@ class SpdylayTests(unittest.TestCase): frame = self.client_streams.recv_frames[0] self.assertEqual(spdylay.SYN_REPLY, frame.frame_type) self.assertEqual(1, frame.stream_id) - self.assertEqual((b':status', b'200 OK'), frame.nv[0]) + self.assertEqual((u':status', u'200 OK'), frame.nv[0]) self.assertEqual(b'Foo the bar', self.client_streams.recv_data.getvalue()) def test_submit_syn_stream_and_syn_stream(self): self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_FIN, 0, 2, - [(b':path', b'/')], None) + [(u':path', u'/')], None) self.client_session.send() self.server_session.recv() @@ -134,10 +134,10 @@ class SpdylayTests(unittest.TestCase): self.assertEqual(1, frame.stream_id) self.assertEqual(0, frame.assoc_stream_id) self.assertEqual(2, frame.pri) - self.assertEqual((b':path', b'/'), frame.nv[0]) + self.assertEqual((u':path', u'/'), frame.nv[0]) self.server_session.submit_syn_reply(spdylay.CTRL_FLAG_FIN, 1, - [(b':version', b'HTTP/1.1')]) + [(u':version', u'HTTP/1.1')]) self.server_session.send() self.client_session.recv() @@ -145,11 +145,11 @@ class SpdylayTests(unittest.TestCase): frame = self.client_streams.recv_frames[0] self.assertEqual(spdylay.SYN_REPLY, frame.frame_type) self.assertEqual(1, frame.stream_id) - self.assertEqual((b':version', b'HTTP/1.1'), frame.nv[0]) + self.assertEqual((u':version', u'HTTP/1.1'), frame.nv[0]) def test_submit_rst_stream(self): self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_FIN, 0, 2, - [(b':path', b'/')], None) + [(u':path', u'/')], None) self.client_session.send() self.server_session.recv() @@ -199,7 +199,7 @@ class SpdylayTests(unittest.TestCase): data_prd = spdylay.DataProvider(io.BytesIO(b'Hello World'), deferred_read_cb) - self.client_session.submit_request(0, [(b':method', b'POST')], + self.client_session.submit_request(0, [(u':method', u'POST')], data_prd=data_prd, stream_user_data=data_prd) self.client_session.send() @@ -211,7 +211,7 @@ class SpdylayTests(unittest.TestCase): self.assertEqual(1, frame.stream_id) self.assertEqual(0, frame.assoc_stream_id) self.assertEqual(0, frame.pri) - self.assertEqual((b':method', b'POST'), frame.nv[0]) + self.assertEqual((u':method', u'POST'), frame.nv[0]) self.assertEqual(b'', self.server_streams.recv_data.getvalue()) @@ -268,7 +268,7 @@ class SpdylayTests(unittest.TestCase): def test_submit_data(self): self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_NONE, 0, 2, - [(b':path', b'/')], None) + [(u':path', u'/')], None) self.client_session.send() self.server_session.recv() @@ -287,7 +287,7 @@ class SpdylayTests(unittest.TestCase): def test_submit_headers(self): self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_NONE, 0, 2, - [(b':path', b'/')], None) + [(u':path', u'/')], None) self.client_session.send() self.server_session.recv() @@ -297,7 +297,7 @@ class SpdylayTests(unittest.TestCase): self.assertEqual(1, frame.stream_id) self.client_session.submit_headers(spdylay.CTRL_FLAG_FIN, 1, - [(b':host', b'localhost')]) + [(u':host', u'localhost')]) self.client_session.send() self.server_session.recv() @@ -305,7 +305,7 @@ class SpdylayTests(unittest.TestCase): frame = self.server_streams.recv_frames[1] self.assertEqual(spdylay.HEADERS, frame.frame_type) self.assertEqual(1, frame.stream_id) - self.assertEqual((b':host', b'localhost'), frame.nv[0]) + self.assertEqual((u':host', u'localhost'), frame.nv[0]) def test_submit_ping(self): self.client_session.submit_ping() @@ -319,7 +319,7 @@ class SpdylayTests(unittest.TestCase): def test_submit_window_update(self): self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_NONE, 0, 2, - [(b':path', b'/')], None) + [(u':path', u'/')], None) self.client_session.send() self.server_session.recv() diff --git a/python/spdyserv.py b/python/spdyserv.py index 9d31a1d0..d41e98a0 100644 --- a/python/spdyserv.py +++ b/python/spdyserv.py @@ -46,8 +46,8 @@ def on_request_recv_cb(session, stream_id): if stream_id in ssctrl.streams: stctrl = ssctrl.streams[stream_id] for name, value in stctrl.headers: - if name == b'user-agent': - user_agent = value.decode('utf-8') + if name == 'user-agent': + user_agent = value break else: user_agent = '' @@ -65,9 +65,9 @@ def on_request_recv_cb(session, stream_id): read_cb) stctrl.data_prd = data_prd - nv = [(b':status', b'200 OK'), - (b':version', b'HTTP/1.1'), - (b'server', b'python-spdylay')] + nv = [(':status', '200 OK'), + (':version', 'HTTP/1.1'), + ('server', 'python-spdylay')] session.submit_response(stream_id, nv, data_prd) class StreamCtrl: