python: add on_stream_close_cb and on_request_recv_cb

This commit is contained in:
Tatsuhiro Tsujikawa 2012-08-17 23:39:48 +09:00
parent 2a5b7bc2a2
commit 6eba7b4af5
3 changed files with 71 additions and 12 deletions

View File

@ -159,11 +159,20 @@ cdef extern from 'spdylay/spdylay.h':
(spdylay_session *session, uint8_t flags, int32_t stream_id, (spdylay_session *session, uint8_t flags, int32_t stream_id,
uint8_t *data, size_t len, void *user_data) uint8_t *data, size_t len, void *user_data)
ctypedef void (*spdylay_on_stream_close_callback)\
(spdylay_session *session, int32_t stream_id,
spdylay_status_code status_code, void *user_data)
ctypedef void (*spdylay_on_request_recv_callback)\
(spdylay_session *session, int32_t stream_id, void *user_data)
ctypedef struct spdylay_session_callbacks: ctypedef struct spdylay_session_callbacks:
spdylay_send_callback send_callback spdylay_send_callback send_callback
spdylay_recv_callback recv_callback spdylay_recv_callback recv_callback
spdylay_on_ctrl_recv_callback on_ctrl_recv_callback spdylay_on_ctrl_recv_callback on_ctrl_recv_callback
spdylay_on_data_chunk_recv_callback on_data_chunk_recv_callback spdylay_on_data_chunk_recv_callback on_data_chunk_recv_callback
spdylay_on_stream_close_callback on_stream_close_callback
spdylay_on_request_recv_callback on_request_recv_callback
int spdylay_session_client_new(spdylay_session **session_ptr, int spdylay_session_client_new(spdylay_session **session_ptr,
int version, int version,

View File

@ -326,6 +326,31 @@ cdef void on_data_chunk_recv_callback(cspdylay.spdylay_session *session,
except BaseException as e: except BaseException as e:
pysession.base_error = e pysession.base_error = e
cdef void on_stream_close_callback(cspdylay.spdylay_session *session,
int32_t stream_id,
cspdylay.spdylay_status_code status_code,
void *user_data):
cdef Session pysession = <Session>user_data
if pysession.on_stream_close_cb:
try:
pysession.on_stream_close_cb(pysession, stream_id, status_code)
except Exception as e:
pysession.error = e
except BaseException as e:
pysession.base_error = e
cdef void on_request_recv_callback(cspdylay.spdylay_session *session,
int32_t stream_id,
void *user_data):
cdef Session pysession = <Session>user_data
if pysession.on_request_recv_cb:
try:
pysession.on_request_recv_cb(pysession, stream_id)
except Exception as e:
pysession.error = e
except BaseException as e:
pysession.base_error = e
cdef ssize_t read_callback(cspdylay.spdylay_session *session, cdef ssize_t read_callback(cspdylay.spdylay_session *session,
int32_t stream_id, uint8_t *buf, size_t length, int32_t stream_id, uint8_t *buf, size_t length,
int *eof, cspdylay.spdylay_data_source *source, int *eof, cspdylay.spdylay_data_source *source,
@ -365,7 +390,8 @@ cdef class Session:
cdef object send_callback cdef object send_callback
cdef object on_ctrl_recv_cb cdef object on_ctrl_recv_cb
cdef object on_data_chunk_recv_cb cdef object on_data_chunk_recv_cb
cdef object on_stream_close_cb
cdef object on_request_recv_cb
cdef object user_data cdef object user_data
cdef object error cdef object error
@ -379,6 +405,8 @@ cdef class Session:
recv_cb=None, send_cb=None, recv_cb=None, send_cb=None,
on_data_chunk_recv_cb=None, on_data_chunk_recv_cb=None,
on_ctrl_recv_cb=None, on_ctrl_recv_cb=None,
on_stream_close_cb=None,
on_request_recv_cb=None,
user_data=None): user_data=None):
cdef cspdylay.spdylay_session_callbacks c_session_callbacks cdef cspdylay.spdylay_session_callbacks c_session_callbacks
cdef int rv cdef int rv
@ -399,8 +427,10 @@ cdef class Session:
# c_session_callbacks.on_ctrl_send_callback = NULL # c_session_callbacks.on_ctrl_send_callback = NULL
# c_session_callbacks.on_ctrl_not_send_callback = NULL # c_session_callbacks.on_ctrl_not_send_callback = NULL
# c_session_callbacks.on_data_send_callback = NULL # c_session_callbacks.on_data_send_callback = NULL
# c_session_callbacks.on_stream_close_callback = NULL c_session_callbacks.on_stream_close_callback = \
# c_session_callbacks.on_request_recv_callback = NULL <cspdylay.spdylay_on_stream_close_callback>on_stream_close_callback
c_session_callbacks.on_request_recv_callback = \
<cspdylay.spdylay_on_request_recv_callback>on_request_recv_callback
# c_session_callbacks.get_credential_proof = NULL # c_session_callbacks.get_credential_proof = NULL
# c_session_callbacks.get_credential_ncerts = NULL # c_session_callbacks.get_credential_ncerts = NULL
# c_session_callbacks.get_credential_cert = NULL # c_session_callbacks.get_credential_cert = NULL
@ -411,6 +441,9 @@ cdef class Session:
self.send_callback = send_cb self.send_callback = send_cb
self.on_data_chunk_recv_cb = on_data_chunk_recv_cb self.on_data_chunk_recv_cb = on_data_chunk_recv_cb
self.on_ctrl_recv_cb = on_ctrl_recv_cb self.on_ctrl_recv_cb = on_ctrl_recv_cb
self.on_stream_close_cb = on_stream_close_cb
self.on_request_recv_cb = on_request_recv_cb
self.user_data = user_data self.user_data = user_data
if side == CLIENT: if side == CLIENT:
@ -439,6 +472,8 @@ cdef class Session:
recv_cb=None, send_cb=None, recv_cb=None, send_cb=None,
on_data_chunk_recv_cb=None, on_data_chunk_recv_cb=None,
on_ctrl_recv_cb=None, on_ctrl_recv_cb=None,
on_stream_close_cb=None,
on_request_recv_cb=None,
user_data=None): user_data=None):
pass pass

View File

@ -28,10 +28,23 @@ def read_cb(session, stream_id, length, source):
def on_ctrl_recv_cb(session, frame): def on_ctrl_recv_cb(session, frame):
ssctrl = session.user_data ssctrl = session.user_data
if frame.frame_type == spdylay.SYN_STREAM: if frame.frame_type == spdylay.SYN_STREAM:
# This will crash cookies... stctrl = StreamCtrl(frame.stream_id)
nv = dict(frame.nv) stctrl.headers.extend(frame.nv)
if b'user-agent' in nv: ssctrl.streams[frame.stream_id] = stctrl
user_agent = nv[b'user-agent'].decode('utf-8')
def on_stream_close_cb(session, stream_id, status_code):
ssctrl = session.user_data
if stream_id in ssctrl.streams:
del ssctrl.streams[stream_id]
def on_request_recv_cb(session, stream_id):
ssctrl = session.user_data
if stream_id in ssctrl.streams:
stctrl = ssctrl.streams[stream_id]
for name, value in stctrl.headers:
if name == b'user-agent':
user_agent = value.decode('utf-8')
break
else: else:
user_agent = '' user_agent = ''
html = '''\ html = '''\
@ -47,17 +60,17 @@ def on_ctrl_recv_cb(session, frame):
data_prd = spdylay.DataProvider(io.BytesIO(bytes(html, 'utf-8')), data_prd = spdylay.DataProvider(io.BytesIO(bytes(html, 'utf-8')),
read_cb) read_cb)
stctrl = StreamCtrl(frame.stream_id, data_prd) stctrl.data_prd = data_prd
ssctrl.streams[frame.stream_id] = stctrl
nv = [(b':status', b'200 OK'), nv = [(b':status', b'200 OK'),
(b':version', b'HTTP/1.1'), (b':version', b'HTTP/1.1'),
(b'server', b'python+spdylay')] (b'server', b'python+spdylay')]
session.submit_response(frame.stream_id, nv, data_prd) session.submit_response(stream_id, nv, data_prd)
class StreamCtrl: class StreamCtrl:
def __init__(self, stream_id, data_prd): def __init__(self, stream_id):
self.stream_id = stream_id self.stream_id = stream_id
self.data_prd = data_prd self.data_prd = None
self.headers = []
class SessionCtrl: class SessionCtrl:
def __init__(self, sock): def __init__(self, sock):
@ -83,6 +96,8 @@ class ThreadedSPDYRequestHandler(socketserver.BaseRequestHandler):
version, version,
send_cb=send_cb, send_cb=send_cb,
on_ctrl_recv_cb=on_ctrl_recv_cb, on_ctrl_recv_cb=on_ctrl_recv_cb,
on_stream_close_cb=on_stream_close_cb,
on_request_recv_cb=on_request_recv_cb,
user_data=ssctrl) user_data=ssctrl)
session.submit_settings(\ session.submit_settings(\