python: add Session.submit_headers()
This commit is contained in:
parent
7580c9f671
commit
7a362e23b3
|
@ -384,6 +384,28 @@ Session objects
|
|||
The :py:class:`InvalidArgumentError` will be raised if the *nv*
|
||||
includes empty name or ``None`` value.
|
||||
|
||||
.. py:method:: Session.submit_headers(flags, stream_id, nv)
|
||||
|
||||
Submits HEADERS frame. The *flags* is bitwise OR of the following
|
||||
values:
|
||||
|
||||
* :py:const:`CTRL_FLAG_FIN`
|
||||
|
||||
If *flags* includes :py:const:`CTRL_FLAG_FIN`, this frame has
|
||||
FLAG_FIN flag set.
|
||||
|
||||
The stream which this frame belongs to is given in the
|
||||
*stream_id*. The *nv* is the name/value pairs in this frame.
|
||||
|
||||
The *nv* is a list containing the name/value pairs. The each
|
||||
element is a tuple of 2 bytestrings: name and value (e.g.,
|
||||
``(b'host', b'localhost')``).
|
||||
|
||||
The names in *nv* will be lower-cased when they are sent.
|
||||
|
||||
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
|
||||
|
|
|
@ -99,6 +99,11 @@ cdef extern from 'spdylay/spdylay.h':
|
|||
int32_t stream_id
|
||||
char **nv
|
||||
|
||||
ctypedef struct spdylay_headers:
|
||||
spdylay_ctrl_hd hd
|
||||
int32_t stream_id
|
||||
char **nv
|
||||
|
||||
ctypedef struct spdylay_rst_stream:
|
||||
spdylay_ctrl_hd hd
|
||||
int32_t stream_id
|
||||
|
@ -126,7 +131,7 @@ cdef extern from 'spdylay/spdylay.h':
|
|||
spdylay_settings settings
|
||||
#spdylay_ping ping
|
||||
spdylay_goaway goaway
|
||||
#spdylay_headers headers
|
||||
spdylay_headers headers
|
||||
#spdylay_window_update window_update
|
||||
#spdylay_credential credential
|
||||
|
||||
|
@ -233,6 +238,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_headers(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)
|
||||
|
||||
|
|
|
@ -104,6 +104,24 @@ cdef class SynReplyFrame(CtrlFrame):
|
|||
def __get__(self):
|
||||
return self.nv
|
||||
|
||||
cdef class HeadersFrame(CtrlFrame):
|
||||
cdef int32_t stream_id
|
||||
cdef object nv
|
||||
|
||||
cdef void fill(self, cspdylay.spdylay_headers *frame):
|
||||
self.fillhd(&frame.hd)
|
||||
|
||||
self.stream_id = frame.stream_id
|
||||
self.nv = cnv2pynv(frame.nv)
|
||||
|
||||
property stream_id:
|
||||
def __get__(self):
|
||||
return self.stream_id
|
||||
|
||||
property nv:
|
||||
def __get__(self):
|
||||
return self.nv
|
||||
|
||||
cdef class RstStreamFrame(CtrlFrame):
|
||||
cdef int32_t stream_id
|
||||
cdef uint32_t status_code
|
||||
|
@ -218,6 +236,7 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session,
|
|||
void *user_data):
|
||||
cdef SynStreamFrame syn_stream
|
||||
cdef SynReplyFrame syn_reply
|
||||
cdef HeadersFrame headers
|
||||
cdef RstStreamFrame rst_stream
|
||||
cdef SettingsFrame settings
|
||||
cdef GoawayFrame goaway
|
||||
|
@ -236,6 +255,10 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session,
|
|||
syn_reply = SynReplyFrame()
|
||||
syn_reply.fill(&frame.syn_reply)
|
||||
pyframe = syn_reply
|
||||
elif frame_type == cspdylay.SPDYLAY_HEADERS:
|
||||
headers = HeadersFrame()
|
||||
headers.fill(&frame.headers)
|
||||
pyframe = headers
|
||||
elif frame_type == cspdylay.SPDYLAY_RST_STREAM:
|
||||
rst_stream = RstStreamFrame()
|
||||
rst_stream.fill(&frame.rst_stream)
|
||||
|
@ -644,6 +667,19 @@ cdef class Session:
|
|||
elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
|
||||
raise MemoryError()
|
||||
|
||||
cpdef submit_headers(self, flags, stream_id, nv):
|
||||
cdef char **cnv = pynv2cnv(nv)
|
||||
cdef int rv
|
||||
rv = cspdylay.spdylay_submit_headers(self._c_session,
|
||||
flags, stream_id, cnv)
|
||||
free(cnv)
|
||||
if rv == 0:
|
||||
return
|
||||
elif rv == cspdylay.SPDYLAY_ERR_INVALID_ARGUMENT:
|
||||
raise InvalidArgumentError(cspdylay.spdylay_strerror(rv))
|
||||
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
|
||||
|
|
|
@ -282,5 +282,27 @@ class SpdylayTests(unittest.TestCase):
|
|||
self.assertEqual(b'Hello World',
|
||||
self.server_streams.recv_data.getvalue())
|
||||
|
||||
def test_submit_headers(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.client_session.submit_headers(spdylay.CTRL_FLAG_FIN, 1,
|
||||
[(b':host', b'localhost')])
|
||||
self.client_session.send()
|
||||
self.server_session.recv()
|
||||
|
||||
self.assertEqual(2, len(self.server_streams.recv_frames))
|
||||
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])
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue