python: add Session.submit_window_update()

This commit is contained in:
Tatsuhiro Tsujikawa 2012-08-22 02:08:03 +09:00
parent 396d4a7fae
commit 870210e859
4 changed files with 81 additions and 1 deletions

View File

@ -448,6 +448,17 @@ Session objects
The :py:class:`InvalidArgumentError` will be raised if the *iv* The :py:class:`InvalidArgumentError` will be raised if the *iv*
contains duplicate settings ID or invalid value. contains duplicate settings ID or invalid value.
.. py:method:: Session.submit_window_update(stream_id, delta_window_size)
Submits WINDOW_UPDATE frame. The effective range of the
*delta_window_size* is ``[1, (1 << 31)-1]``, inclusive. But the
application must be responsible to keep the resulting window
``size <= (1 << 31)-1``.
The :py:class:`InvalidArgumentError` will be raised if the
*delta_window_size* is 0 or negative. The
:py:class:`StreamClosedError` will be raised if the stream is
already closed or does not exist.
Frame Types Frame Types
----------- -----------

View File

@ -128,6 +128,11 @@ cdef extern from 'spdylay/spdylay.h':
int32_t last_good_stream_id int32_t last_good_stream_id
uint32_t status_code uint32_t status_code
ctypedef struct spdylay_window_update:
spdylay_ctrl_hd hd
int32_t stream_id
int32_t delta_window_size
ctypedef union spdylay_frame: ctypedef union spdylay_frame:
spdylay_syn_stream syn_stream spdylay_syn_stream syn_stream
spdylay_syn_reply syn_reply spdylay_syn_reply syn_reply
@ -136,7 +141,7 @@ cdef extern from 'spdylay/spdylay.h':
spdylay_ping ping spdylay_ping ping
spdylay_goaway goaway spdylay_goaway goaway
spdylay_headers headers spdylay_headers headers
#spdylay_window_update window_update spdylay_window_update window_update
#spdylay_credential credential #spdylay_credential credential
ctypedef union spdylay_data_source: ctypedef union spdylay_data_source:
@ -257,3 +262,7 @@ cdef extern from 'spdylay/spdylay.h':
int spdylay_submit_settings(spdylay_session *session, uint8_t flags, int spdylay_submit_settings(spdylay_session *session, uint8_t flags,
spdylay_settings_entry *iv, size_t niv) spdylay_settings_entry *iv, size_t niv)
int spdylay_submit_window_update(spdylay_session *session,
int32_t stream_id,
int32_t delta_window_size)

View File

@ -22,6 +22,9 @@ class ZlibError(Exception):
class UnsupportedVersionError(Exception): class UnsupportedVersionError(Exception):
pass pass
class StreamClosedError(Exception):
pass
class DataProvider: class DataProvider:
def __init__(self, source, read_cb): def __init__(self, source, read_cb):
self.source = source self.source = source
@ -183,6 +186,24 @@ cdef class GoawayFrame(CtrlFrame):
def __get__(self): def __get__(self):
return self.status_code return self.status_code
cdef class WindowUpdateFrame(CtrlFrame):
cdef int32_t stream_id
cdef int32_t delta_window_size
cdef void fill(self, cspdylay.spdylay_window_update *frame):
self.fillhd(&frame.hd)
self.stream_id = frame.stream_id
self.delta_window_size = frame.delta_window_size
property stream_id:
def __get__(self):
return self.stream_id
property delta_window_size:
def __get__(self):
return self.delta_window_size
cdef object cnv2pynv(char **nv): cdef object cnv2pynv(char **nv):
''' Convert C-style name/value pairs ``nv`` to Python style ''' Convert C-style name/value pairs ``nv`` to Python style
pairs. ''' pairs. '''
@ -253,6 +274,7 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session,
cdef SettingsFrame settings cdef SettingsFrame settings
cdef PingFrame ping cdef PingFrame ping
cdef GoawayFrame goaway cdef GoawayFrame goaway
cdef WindowUpdateFrame window_update
cdef Session pysession = <Session>user_data cdef Session pysession = <Session>user_data
@ -288,6 +310,10 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session,
goaway = GoawayFrame() goaway = GoawayFrame()
goaway.fill(&frame.goaway) goaway.fill(&frame.goaway)
pyframe = goaway pyframe = goaway
elif frame_type == cspdylay.SPDYLAY_WINDOW_UPDATE:
window_update = WindowUpdateFrame()
window_update.fill(&frame.window_update)
pyframe = window_update
if pyframe: if pyframe:
try: try:
@ -739,6 +765,19 @@ cdef class Session:
elif rv == cspdylay.SPDYLAY_ERR_NOMEM: elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
raise MemoryError() raise MemoryError()
cpdef submit_window_update(self, stream_id, delta_window_size):
cdef int rv
rv = cspdylay.spdylay_submit_window_update(self._c_session, stream_id,
delta_window_size)
if rv == 0:
return
elif rv == cspdylay.SPDYLAY_ERR_INVALID_ARGUMENT:
raise InvalidArgumentError()
elif rv == cspdylay.SPDYLAY_ERR_STREAM_CLOSED:
raise StreamClosedError()
elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
raise MemoryError()
cpdef submit_settings(self, flags, iv): cpdef submit_settings(self, flags, iv):
''' Submit SETTINGS frame. iv is list of tuple (settings_id, ''' Submit SETTINGS frame. iv is list of tuple (settings_id,
flag, value) flag, value)

View File

@ -314,5 +314,26 @@ class SpdylayTests(unittest.TestCase):
self.assertEqual(spdylay.PING, frame.frame_type) self.assertEqual(spdylay.PING, frame.frame_type)
self.assertEqual(1, frame.unique_id) self.assertEqual(1, frame.unique_id)
def test_submit_window_update(self):
self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_NONE, 0, 2,
[(b':path', b'/')], None)
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.SYN_STREAM, frame.frame_type)
self.assertEqual(1, frame.stream_id)
self.server_session.submit_window_update(1, 4096)
self.server_session.send()
self.client_session.recv()
self.assertEqual(1, len(self.client_streams.recv_frames))
frame = self.client_streams.recv_frames[0]
self.assertEqual(spdylay.WINDOW_UPDATE, frame.frame_type)
self.assertEqual(1, frame.stream_id)
self.assertEqual(4096, frame.delta_window_size)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()