python: add Session.submit_data()
This commit is contained in:
parent
78f6119196
commit
7580c9f671
|
@ -262,10 +262,14 @@ Session objects
|
|||
request message bodies
|
||||
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9) must
|
||||
be specified with ``:method`` key in nv (e.g. ``POST``). The type
|
||||
of *data_prd* is expected to be :py:class:`DataProvider`. This
|
||||
method does not increase reference count of *data_prd*, so the
|
||||
application must hold the reference to it until the stream is
|
||||
closed. If *data_prd* is ``None``, SYN_STREAM have FLAG_FIN set.
|
||||
of *data_prd* is expected to be :py:class:`DataProvider`. If
|
||||
*data_prd* is ``None``, SYN_STREAM have FLAG_FIN set.
|
||||
|
||||
.. note::
|
||||
|
||||
This method does not increase reference count of *data_prd*,
|
||||
so the application must hold the reference to it until the
|
||||
stream is closed.
|
||||
|
||||
The *stream_user_data* is data associated to the stream opened by
|
||||
this request and can be an arbitrary object, which can be
|
||||
|
@ -309,10 +313,14 @@ Session objects
|
|||
|
||||
If *data_prd* is not ``None``, it provides data which will be sent
|
||||
in subsequent DATA frames. The type of *data_prd* is expected to
|
||||
be :py:class:`DataProvider`. This method does not increase
|
||||
reference count of *data_prd*, so the application must hold the
|
||||
reference to it until the stream is closed. If *data_prd* is
|
||||
``None``, SYN_REPLY have FLAG_FIN set.
|
||||
be :py:class:`DataProvider`. If *data_prd* is ``None``, SYN_REPLY
|
||||
have FLAG_FIN set.
|
||||
|
||||
.. note::
|
||||
|
||||
This method does not increase reference count of *data_prd*,
|
||||
so the application must hold the reference to it until the
|
||||
stream is closed.
|
||||
|
||||
The :py:class:`InvalidArgumentError` will be raised if the *nv*
|
||||
includes empty name or ``None`` value.
|
||||
|
@ -376,6 +384,20 @@ Session objects
|
|||
The :py:class:`InvalidArgumentError` will be raised if the *nv*
|
||||
includes empty name or ``None`` value.
|
||||
|
||||
.. py:method:: Session.submit_data(stream_id, flags, data_prd)
|
||||
|
||||
Submits one or more DATA frames to the stream *stream_id*. The
|
||||
data to be sent are provided by *data_prd*. The type of
|
||||
*data_prd* is expected to be :py:class:`DataProvider`. If *flags*
|
||||
contains :py:const:`DATA_FLAG_FIN`, the last DATA frame has
|
||||
FLAG_FIN set.
|
||||
|
||||
.. note::
|
||||
|
||||
This method does not increase reference count of *data_prd*,
|
||||
so the application must hold the reference to it until the
|
||||
stream is closed.
|
||||
|
||||
.. py:method:: Session.submit_rst_stream(stream_id, status_code)
|
||||
|
||||
Submits RST_STREAM frame to cancel/reject the stream *stream_id*
|
||||
|
|
|
@ -233,6 +233,9 @@ cdef extern from 'spdylay/spdylay.h':
|
|||
int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
|
||||
int32_t stream_id, char **nv)
|
||||
|
||||
int spdylay_submit_data(spdylay_session *session, int32_t stream_id,
|
||||
uint8_t flags, spdylay_data_provider *data_prd)
|
||||
|
||||
int spdylay_submit_rst_stream(spdylay_session *session,
|
||||
int32_t stream_id, uint32_t status_code)
|
||||
|
||||
|
|
|
@ -644,6 +644,23 @@ cdef class Session:
|
|||
elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
|
||||
raise MemoryError()
|
||||
|
||||
cpdef submit_data(self, stream_id, flags, data_prd):
|
||||
cdef cspdylay.spdylay_data_provider c_data_prd
|
||||
cdef cspdylay.spdylay_data_provider *c_data_prd_ptr
|
||||
cpdef int rv
|
||||
if data_prd:
|
||||
create_c_data_prd(&c_data_prd, data_prd)
|
||||
c_data_prd_ptr = &c_data_prd
|
||||
else:
|
||||
c_data_prd_ptr = NULL
|
||||
|
||||
rv = cspdylay.spdylay_submit_data(self._c_session, stream_id,
|
||||
flags, c_data_prd_ptr)
|
||||
if rv == 0:
|
||||
return
|
||||
elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
|
||||
raise MemoryError()
|
||||
|
||||
cpdef submit_rst_stream(self, stream_id, status_code):
|
||||
cdef int rv
|
||||
rv = cspdylay.spdylay_submit_rst_stream(self._c_session, stream_id,
|
||||
|
|
|
@ -121,9 +121,9 @@ class SpdylayTests(unittest.TestCase):
|
|||
|
||||
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);
|
||||
self.client_session.send();
|
||||
self.server_session.recv();
|
||||
[(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]
|
||||
|
@ -135,8 +135,8 @@ class SpdylayTests(unittest.TestCase):
|
|||
|
||||
self.server_session.submit_syn_reply(spdylay.CTRL_FLAG_FIN, 1,
|
||||
[(b':version', b'HTTP/1.1')])
|
||||
self.server_session.send();
|
||||
self.client_session.recv();
|
||||
self.server_session.send()
|
||||
self.client_session.recv()
|
||||
|
||||
self.assertEqual(1, len(self.client_streams.recv_frames))
|
||||
frame = self.client_streams.recv_frames[0]
|
||||
|
@ -146,13 +146,13 @@ class SpdylayTests(unittest.TestCase):
|
|||
|
||||
def test_submit_rst_stream(self):
|
||||
self.client_session.submit_syn_stream(spdylay.CTRL_FLAG_FIN, 0, 2,
|
||||
[(b':path', b'/')], None);
|
||||
self.client_session.send();
|
||||
self.server_session.recv();
|
||||
[(b':path', b'/')], None)
|
||||
self.client_session.send()
|
||||
self.server_session.recv()
|
||||
|
||||
self.server_session.submit_rst_stream(1, spdylay.PROTOCOL_ERROR)
|
||||
self.server_session.send();
|
||||
self.client_session.recv();
|
||||
self.server_session.send()
|
||||
self.client_session.recv()
|
||||
|
||||
self.assertEqual(1, len(self.client_streams.recv_frames))
|
||||
frame = self.client_streams.recv_frames[0]
|
||||
|
@ -162,8 +162,8 @@ class SpdylayTests(unittest.TestCase):
|
|||
|
||||
def test_submit_goaway(self):
|
||||
self.client_session.submit_goaway(spdylay.GOAWAY_PROTOCOL_ERROR)
|
||||
self.client_session.send();
|
||||
self.server_session.recv();
|
||||
self.client_session.send()
|
||||
self.server_session.recv()
|
||||
|
||||
self.assertEqual(1, len(self.server_streams.recv_frames))
|
||||
frame = self.server_streams.recv_frames[0]
|
||||
|
@ -179,8 +179,8 @@ class SpdylayTests(unittest.TestCase):
|
|||
|
||||
def test_fail_session(self):
|
||||
self.client_session.fail_session(spdylay.GOAWAY_PROTOCOL_ERROR)
|
||||
self.client_session.send();
|
||||
self.server_session.recv();
|
||||
self.client_session.send()
|
||||
self.server_session.recv()
|
||||
|
||||
self.assertEqual(1, len(self.server_streams.recv_frames))
|
||||
frame = self.server_streams.recv_frames[0]
|
||||
|
@ -263,5 +263,24 @@ class SpdylayTests(unittest.TestCase):
|
|||
with self.assertRaises(spdylay.CallbackFailureError):
|
||||
self.client_session.send()
|
||||
|
||||
def test_submit_data(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)
|
||||
|
||||
data_prd = spdylay.DataProvider(io.BytesIO(b'Hello World'), read_cb)
|
||||
self.client_session.submit_data(1, spdylay.DATA_FLAG_FIN, data_prd)
|
||||
self.client_session.send()
|
||||
self.server_session.recv()
|
||||
|
||||
self.assertEqual(b'Hello World',
|
||||
self.server_streams.recv_data.getvalue())
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue