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*
|
The :py:class:`InvalidArgumentError` will be raised if the *nv*
|
||||||
includes empty name or ``None`` value.
|
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)
|
.. py:method:: Session.submit_data(stream_id, flags, data_prd)
|
||||||
|
|
||||||
Submits one or more DATA frames to the stream *stream_id*. The
|
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
|
int32_t stream_id
|
||||||
char **nv
|
char **nv
|
||||||
|
|
||||||
|
ctypedef struct spdylay_headers:
|
||||||
|
spdylay_ctrl_hd hd
|
||||||
|
int32_t stream_id
|
||||||
|
char **nv
|
||||||
|
|
||||||
ctypedef struct spdylay_rst_stream:
|
ctypedef struct spdylay_rst_stream:
|
||||||
spdylay_ctrl_hd hd
|
spdylay_ctrl_hd hd
|
||||||
int32_t stream_id
|
int32_t stream_id
|
||||||
|
@ -126,7 +131,7 @@ cdef extern from 'spdylay/spdylay.h':
|
||||||
spdylay_settings settings
|
spdylay_settings settings
|
||||||
#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
|
||||||
|
|
||||||
|
@ -233,6 +238,9 @@ cdef extern from 'spdylay/spdylay.h':
|
||||||
int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
|
int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
|
||||||
int32_t stream_id, char **nv)
|
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,
|
int spdylay_submit_data(spdylay_session *session, int32_t stream_id,
|
||||||
uint8_t flags, spdylay_data_provider *data_prd)
|
uint8_t flags, spdylay_data_provider *data_prd)
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,24 @@ cdef class SynReplyFrame(CtrlFrame):
|
||||||
def __get__(self):
|
def __get__(self):
|
||||||
return self.nv
|
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 class RstStreamFrame(CtrlFrame):
|
||||||
cdef int32_t stream_id
|
cdef int32_t stream_id
|
||||||
cdef uint32_t status_code
|
cdef uint32_t status_code
|
||||||
|
@ -218,6 +236,7 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session,
|
||||||
void *user_data):
|
void *user_data):
|
||||||
cdef SynStreamFrame syn_stream
|
cdef SynStreamFrame syn_stream
|
||||||
cdef SynReplyFrame syn_reply
|
cdef SynReplyFrame syn_reply
|
||||||
|
cdef HeadersFrame headers
|
||||||
cdef RstStreamFrame rst_stream
|
cdef RstStreamFrame rst_stream
|
||||||
cdef SettingsFrame settings
|
cdef SettingsFrame settings
|
||||||
cdef GoawayFrame goaway
|
cdef GoawayFrame goaway
|
||||||
|
@ -236,6 +255,10 @@ cdef void on_ctrl_recv_callback(cspdylay.spdylay_session *session,
|
||||||
syn_reply = SynReplyFrame()
|
syn_reply = SynReplyFrame()
|
||||||
syn_reply.fill(&frame.syn_reply)
|
syn_reply.fill(&frame.syn_reply)
|
||||||
pyframe = 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:
|
elif frame_type == cspdylay.SPDYLAY_RST_STREAM:
|
||||||
rst_stream = RstStreamFrame()
|
rst_stream = RstStreamFrame()
|
||||||
rst_stream.fill(&frame.rst_stream)
|
rst_stream.fill(&frame.rst_stream)
|
||||||
|
@ -644,6 +667,19 @@ cdef class Session:
|
||||||
elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
|
elif rv == cspdylay.SPDYLAY_ERR_NOMEM:
|
||||||
raise MemoryError()
|
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):
|
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
|
||||||
cdef cspdylay.spdylay_data_provider *c_data_prd_ptr
|
cdef cspdylay.spdylay_data_provider *c_data_prd_ptr
|
||||||
|
|
|
@ -282,5 +282,27 @@ class SpdylayTests(unittest.TestCase):
|
||||||
self.assertEqual(b'Hello World',
|
self.assertEqual(b'Hello World',
|
||||||
self.server_streams.recv_data.getvalue())
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue