diff --git a/doc/python.rst b/doc/python.rst index a7d62da7..a079c590 100644 --- a/doc/python.rst +++ b/doc/python.rst @@ -426,6 +426,10 @@ Session objects with the status code *status_code*. See `Stream Status Codes`_ for available status codes. +.. py:method:: Session.submit_ping() + + Submits PING frame. + .. py:method:: Session.submit_goaway(status_code) Submits GOAWAY frame. The status code *status_code* is ignored if diff --git a/python/cspdylay.pxd b/python/cspdylay.pxd index d5f71fad..5435f0c5 100644 --- a/python/cspdylay.pxd +++ b/python/cspdylay.pxd @@ -119,6 +119,10 @@ cdef extern from 'spdylay/spdylay.h': size_t niv spdylay_settings_entry *iv + ctypedef struct spdylay_ping: + spdylay_ctrl_hd hd + uint32_t unique_id + ctypedef struct spdylay_goaway: spdylay_ctrl_hd hd int32_t last_good_stream_id @@ -129,7 +133,7 @@ cdef extern from 'spdylay/spdylay.h': spdylay_syn_reply syn_reply spdylay_rst_stream rst_stream spdylay_settings settings - #spdylay_ping ping + spdylay_ping ping spdylay_goaway goaway spdylay_headers headers #spdylay_window_update window_update @@ -247,6 +251,8 @@ cdef extern from 'spdylay/spdylay.h': int spdylay_submit_rst_stream(spdylay_session *session, int32_t stream_id, uint32_t status_code) + int spdylay_submit_ping(spdylay_session *session) + int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code) int spdylay_submit_settings(spdylay_session *session, uint8_t flags, diff --git a/python/spdylay.pyx b/python/spdylay.pyx index 3f9c2886..f1ee17a5 100644 --- a/python/spdylay.pyx +++ b/python/spdylay.pyx @@ -153,6 +153,18 @@ cdef class SettingsFrame(CtrlFrame): def __get__(self): return self.iv +cdef class PingFrame(CtrlFrame): + cdef uint32_t unique_id + + cdef void fill(self, cspdylay.spdylay_ping *frame): + self.fillhd(&frame.hd) + + self.unique_id = frame.unique_id + + property unique_id: + def __get__(self): + return self.unique_id + cdef class GoawayFrame(CtrlFrame): cdef int32_t last_good_stream_id cdef uint32_t status_code @@ -239,6 +251,7 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session, cdef HeadersFrame headers cdef RstStreamFrame rst_stream cdef SettingsFrame settings + cdef PingFrame ping cdef GoawayFrame goaway cdef Session pysession = user_data @@ -267,6 +280,10 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session, settings = SettingsFrame() settings.fill(&frame.settings) pyframe = settings + elif frame_type == cspdylay.SPDYLAY_PING: + ping = PingFrame() + ping.fill(&frame.ping) + pyframe = ping elif frame_type == cspdylay.SPDYLAY_GOAWAY: goaway = GoawayFrame() goaway.fill(&frame.goaway) @@ -706,6 +723,14 @@ cdef class Session: elif rv == cspdylay.SPDYLAY_ERR_NOMEM: raise MemoryError() + cpdef submit_ping(self): + cdef int rv + rv = cspdylay.spdylay_submit_ping(self._c_session) + if rv == 0: + return + elif rv == cspdylay.SPDYLAY_ERR_NOMEM: + raise MemoryError() + cpdef submit_goaway(self, status_code): cdef int rv rv = cspdylay.spdylay_submit_goaway(self._c_session, status_code) diff --git a/python/spdylay_tests.py b/python/spdylay_tests.py index 27dbd854..fa4ec632 100644 --- a/python/spdylay_tests.py +++ b/python/spdylay_tests.py @@ -304,5 +304,15 @@ class SpdylayTests(unittest.TestCase): self.assertEqual(1, frame.stream_id) self.assertEqual((b':host', b'localhost'), frame.nv[0]) + def test_submit_ping(self): + self.client_session.submit_ping() + self.client_session.send() + self.server_session.recv() + + self.assertEqual(1, len(self.server_streams.recv_frames)) + frame = self.server_streams.recv_frames[0] + self.assertEqual(spdylay.PING, frame.frame_type) + self.assertEqual(1, frame.unique_id) + if __name__ == '__main__': unittest.main()