Python-spdylay - Spdylay Python Extension Module¶
Python-spdylay is the Python extension module of Spdylay SPDY C library.
Build¶
To generate C source code from spdylay.pyx
, run cython
:
$ cython spdylay.pyx
To build extension, run setup.py
:
$ python setup.py build_ext
Session Objects¶
-
class
spdylay.
Session
(side, version, config=None, send_cb=None, recv_cb=None, on_ctrl_recv_cb=None, on_invalid_ctrl_recv_cb=None, on_data_chunk_recv_cb=None, on_data_recv_cb=None, before_ctrl_send_cb=None, on_ctrl_send_cb=None, on_ctrl_not_send_cb=None, on_data_send_cb=None, on_stream_close_cb=None, on_request_recv_cb=None, on_ctrl_recv_parse_error_cb=None, on_unknown_ctrl_recv_cb=None, user_data=None)¶ This is the class to hold the resources needed for a SPDY session. Sending and receiving SPDY frames are done using the methods of this class.
The side specifies server or client. Use one of the following:
-
CLIENT
¶ Indicates client.
-
SERVER
¶ Indicates server.
The version specifies SPDY protocol version. Use of the following:
-
PROTO_SPDY2
¶ Indicates SPDY/2.
-
PROTO_SPDY3
¶ Indicates SPDY/3.
The user_data specifies opaque object tied to this object. It can be accessed through
user_data
attribute.The recv_cb specifies callback function (callable) invoked when the object wants to receive data from the remote peer. The signature of this callback is:
-
recv_cb
(session, length)¶ The session is the
Session
object invoking the callback. The implementation of this function must read at most length bytes of bytestring and return it. If it cannot read any single byte without blocking, it must return empty bytestring orNone
. If it gets EOF before it reads any single byte, it must raiseEOFError
. For other errors, it must raiseCallbackFailureError
.
The send_cb specifies callback function (callable) invoked when session wants to send data to the remote peer. The signature of this callback is:
-
send_cb
(session, data)¶ The session is the
Session
object invoking the callback. The data is the bytestring to send. The implementation of this function will send all or part of data. It must return the number of bytes sent if it succeeds. If it cannot send any single byte without blocking, it must return 0 orNone
. For other errors, it must returnCallbackFailureError
.
The on_ctrl_recv_cb specifies callback function (callable) invoked when a control frame is received.
-
on_ctrl_recv_cb
(session, frame)¶ The session is the
Session
object invoking the callback. The frame is the received control frame.frame.frame_type
tells the type of frame. See Frame Types for the details. Once the frame type is identified, access attribute of the frame to get information.
The on_invalid_ctrl_recv_cb specifies callback function (callable) invoked when an invalid control frame is received.
-
on_invalid_ctrl_recv_cb
(session, frame, status_code)¶ The session is the
Session
object invoking the callback. The frame is the received control frame.frame.frame_type
tells the type of frame. See Frame Types for the details. Once the frame type is identified, access attribute of the frame to get information. The status_code is one of the Stream Status Codes and indicates the error. When this callback function is invoked, either RST_STREAM or GOAWAY will be sent.
The on_data_chunk_recv_cb specifies callback function (callable) invoked when a chunk of data in DATA frame is received.
-
on_data_chunk_recv_cb
(session, flags, stream_id, data)¶ The session is the
Session
object invoking the callback. The stream_id is the stream ID this DATA frame belongs to. The flags is the flags of DATA frame which this data chunk is contained.(flags & DATA_FLAG_FIN) != 0
does not necessarily mean this chunk of data is the last one in the stream. You should useon_data_recv_cb()
to know all data frames are received. The data is the bytestring of received data.
The on_data_recv_cb specifies callback function (callable) invoked when DATA frame is received.
-
on_data_recv_cb
(session, flags, stream_id, length)¶ The actual data it contains are received by
on_data_chunk_recv_cb()
.
The before_ctrl_send_cb specifies callback function (callable) invoked before the control frame is sent.
-
before_ctrl_send_cb
(session, frame)¶ The session is the
Session
object invoking the callback. The frame is the control frame to be sent.frame.frame_type
tells the type of frame. See Frame Types for the details. Once the frame type is identified, access attribute of the frame to get information.
The on_ctrl_send_cb specifies callback function (callable) invoked after the control frame is sent.
-
on_ctrl_send_cb
(session, frame)¶ The session is the
Session
object invoking the callback. The frame is the control frame to be sent.frame.frame_type
tells the type of frame. See Frame Types for the details. Once the frame type is identified, access attribute of the frame to get information.
The on_ctrl_not_send_cb specifies callback function (callable) after the control frame is not sent because of the error.
-
on_ctrl_not_send_cb
(session, frame, error_code)¶ The session is the
Session
object invoking the callback. The frame is the received control frame.frame.frame_type
tells the type of frame. See Frame Types for the details. Once the frame type is identified, access attribute of the frame to get information. The error_code is one of the Error Codes and indicates the error.
The on_data_send_cb specifies callback function (callable) invoked after DATA frame is sent.
-
on_data_send_cb
(session, flags, stream_id, length)¶
The on_stream_close_cb specifies callback function (callable) invoked when the stream is closed.
-
on_stream_close_cb
(session, stream_id, status_code)¶ The session is the
Session
object invoking the callback. The stream_id indicates the stream ID. The reason of closure is indicated by the status_code. See Stream Status Codes for the details. The stream_user_data, which was specified insubmit_request()
orsubmit_syn_stream()
, is still available in this function.
The on_request_recv_cb specifies callback function (callable) invoked when the request from the remote peer is received. In other words, the frame with FIN flag set is received. In HTTP, this means HTTP request, including request body, is fully received.
-
on_request_recv_cb
(session, stream_id)¶ The session is the
Session
object invoking the callback. The stream_id indicates the stream ID.
The on_ctrl_recv_parse_error_cb specifies callback function (callable) invoked when the received control frame octets could not be parsed correctly.
-
on_ctrl_recv_parse_error_cb
(session, type, head, payload, error_code)¶ The type indicates the type of received control frame. The head is the bytestring of control frame header. The payload is the bytestring of data portion of the received frame. The error_code is one of the error code defined in Error Codes and indicates the error.
The on_unknown_ctrl_recv_cb specifies callback function (callable) invoked when the received control frame type is unknown.
-
on_unknown_ctrl_recv_cb
(session, head, payload)¶ The head is the bytestring of control frame header. The payload is the bytestring of data portion of the received frame.
The
InvalidArgumentError
will be raised if the given argument is invalid. TheUnsupportedVersionError
will be raised if the version is not supported. TheZlibError
will be raised if initialization of zlib failed.-
-
Session.
user_data
¶ The object passed in the constructor as user_data argument. This attribute is read-only.
-
Session.
send
()¶ Sends pending frames to the remote peer. This method retrieves the highest prioritized frame from the outbound queue and sends it to the remote peer. It does this as many as possible until the user callback
send_cb()
returns 0 orNone
or the outbound queue becomes empty. This method calls several callback functions which are passed when initializing the session. Seespdylay_session_send()
about the callback functions invoked from this method.The
CallbackFailureError
will be raised if the callback function failed.
-
Session.
recv
(data=None)¶ Receives frames from the remote peer. This method receives as many frames as possible until the user callback
recv_cb()
returns empty bytestring orNone
. This function calls several callback functions which are passed when initializing the session. Seespdylay_session_recv()
about the callback functions invoked from this method. If data isNone
, this method will invokerecv_cb()
callback function to receive incoming data. If data is notNone
, it must be a bytestring and this method uses it as the incoming data and does not callrecv_cb()
callback function.The
EOFError
will be raised if the remote peer did shutdown on the connection. TheCallbackFailureError
will be raised if the callback function failed.
-
Session.
resume_data
(stream_id)¶ Puts back previously deferred DATA frame in the stream stream_id to the outbound queue.
This method returns
True
if it succeeds, orFalse
. This method will fail if the stream does not exist or no deferred data exist.
-
Session.
want_read
()¶ Returns
True
if session wants to receive data from the remote peer.If both
want_read()
andwant_write()
returnFalse
, the application should drop the connection.
-
Session.
want_write
()¶ Returns
True
if session wants to send data to the remote peer.If both
want_read()
andwant_write()
returnFalse
, the application should drop the connection.
-
Session.
get_stream_user_data
(stream_id)¶ Returns stream_user_data for the stream stream_id. The stream_user_data is provided by
submit_request()
orsubmit_syn_stream()
. If the stream is initiated by the remote endpoint, stream_user_data is alwaysNone
. If the stream is initiated by the local endpoint andNone
is given insubmit_request()
orsubmit_syn_stream()
, then this function returnsNone
. If the stream does not exist, this function returnsNone
.
-
Session.
get_outbound_queue_size
()¶ Returns the number of frames in the outbound queue. This does not include the deferred DATA frames.
-
Session.
get_pri_lowest
()¶ Returns lowest priority value for the session.
-
Session.
fail_session
(status_code)¶ Submits GOAWAY frame. The status code status_code is ignored if the protocol version is
PROTO_SPDY2
.This method should be called when the connection should be terminated after sending GOAWAY. If the remaining streams should be processed after GOAWAY, use
submit_goaway()
instead.
-
Session.
submit_request
(pri, nv, data_prd=None, stream_user_data=None)¶ Submits SYN_STREAM frame and optionally one or more DATA frames.
The pri is priority of this request.
0
is the highest priority value. Useget_pri_lowest()
to know the lowest priority value for this session.The nv is a list containing the name/value pairs. The each element is a pair of unicode strings: name and value (e.g.,
(u'host', u'localhost')
).The nv must include following name/value pairs:
:method
- HTTP method (e.g.,
GET
,POST
,HEAD
, etc) :scheme
- URI scheme (e.g.,
https
) :path
- Absolute path and parameters of this request (e.g.,
/foo
,/foo;bar;haz?h=j&y=123
) :version
- HTTP version (e.g.,
HTTP/1.1
) :host
- The hostport portion of the URI for this request (e.g.,
example.org:443
). This is the same as the HTTP “Host” header field.
If the session is initialized with the version
PROTO_SPDY2
, the above names are translated tomethod
,scheme
,url
,version
andhost
respectively.The names in nv will be lower-cased when they are sent.
If data_prd is not
None
, it provides data which will be sent in subsequent DATA frames. In this case, a method that allows 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 beDataProvider
. If data_prd isNone
, 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 retrieved later by
get_stream_user_data()
.Since the library reorders the frames and tries to send the highest prioritized one first and the SPDY specification requires the stream ID must be strictly increasing, the stream ID of this request cannot be known until it is about to sent. To know the stream ID of the request, the application can use
before_ctrl_send_cb()
. This callback is called just before the frame is sent. For SYN_STREAM frame, the argument frame has the stream ID assigned. Also since the stream is already opened,get_stream_user_data()
can be used to get stream_user_data to identify which SYN_STREAM we are processing.The
InvalidArgumentError
will be raised if the pri is invalid; or the nv includes empty name orNone
value.
-
Session.
submit_response
(stream_id, nv, data_prd=None)¶ Submits SYN_REPLY frame and optionally one or more DATA frames against the stream stream_id.
The nv is a list containing the name/value pairs. The each element is a pair of unicode strings: name and value (e.g.,
(u'host', u'localhost')
).The nv must include following name/value pairs:
:status
- HTTP status code (e.g.,
200
or200 OK
) :version
- HTTP response version (e.g.,
HTTP/1.1
)
If the session is initialized with the version
PROTO_SPDY2
, the above names are translated tostatus
andversion
respectively.The names in nv will be lower-cased when they are sent.
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 beDataProvider
. If data_prd isNone
, 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
InvalidArgumentError
will be raised if the nv includes empty name orNone
value.
-
Session.
submit_syn_stream
(flags, pri, nv, assoc_stream_id=0, stream_user_data=None)¶ Submits SYN_STREAM frame. The flags is bitwise OR of the following values:
If flags includes
CTRL_FLAG_FIN
, this frame has FLAG_FIN flag set.The assoc_stream_id is used for server-push. Specify 0 if this stream is not server-push. If session is initialized for client use, assoc_stream_id is ignored.
The pri is priority of this request.
0
is the highest priority value. Useget_pri_lowest()
to know the lowest priority value for this session.The nv is a list containing the name/value pairs. The each element is a pair of unicode strings: name and value (e.g.,
(u'host', u'localhost')
).The names in nv will be lower-cased when they are sent.
The stream_user_data is data associated to the stream opened by this request and can be an arbitrary object, which can be retrieved later by
get_stream_user_data()
.This function is low-level in a sense that the application code can specify flags and the Associated-To-Stream-ID directly. For usual HTTP request,
submit_request()
is useful.The
InvalidArgumentError
will be raised if the pri is invalid; or the assoc_stream_id is invalid; or the nv includes empty name orNone
value.
-
Session.
submit_syn_reply
(flags, stream_id, nv)¶ Submits SYN_REPLY frame. The flags is bitwise OR of the following values:
If flags includes
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 pair of unicode strings: name and value (e.g.,
(u'host', u'localhost')
).The names in nv will be lower-cased when they are sent.
The
InvalidArgumentError
will be raised if the nv includes empty name orNone
value.
-
Session.
submit_headers
(flags, stream_id, nv)¶ Submits HEADERS frame. The flags is bitwise OR of the following values:
If flags includes
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 pair of unicode strings: name and value (e.g.,
(u'host', u'localhost')
).The names in nv will be lower-cased when they are sent.
The
InvalidArgumentError
will be raised if the nv includes empty name orNone
value.
-
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
DataProvider
. If flags containsDATA_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.
-
Session.
submit_rst_stream
(stream_id, status_code)¶ Submits RST_STREAM frame to cancel/reject the stream stream_id with the status code status_code. See Stream Status Codes for available status codes.
-
Session.
submit_ping
()¶ Submits PING frame.
-
Session.
submit_goaway
(status_code)¶ Submits GOAWAY frame. The status code status_code is ignored if the protocol version is
PROTO_SPDY2
. See GOAWAY Status Codes for available status codes.
-
Session.
submit_settings
(flags, iv)¶ Stores local settings and submits SETTINGS frame. The flags is bitwise OR of the values described in SETTINGS Frame Flags.
The iv is a list of tuple
(settings_id, flag, value)
. For settings_id, see SETTINGS IDs. For flag, see SETTINGS ID Flags.The
InvalidArgumentError
will be raised if the iv contains duplicate settings ID or invalid value.
-
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 windowsize <= (1 << 31)-1
.The
InvalidArgumentError
will be raised if the delta_window_size is 0 or negative. TheStreamClosedError
will be raised if the stream is already closed or does not exist.
Helper Functions¶
-
spdylay.
get_npn_protocols
()¶ Returns SPDY version strings which can be directly passed to
ssl.SSLContext.set_npn_protocols()
. Please note that the returned list only includes SPDY version strings this library supports. If the application intends to support other fallback protocols (e.g.,http/1.1
), the application should add them to the returned list.
-
spdylay.
npn_get_version
(proto)¶ Returns SPDY version which spdylay library supports from the given protocol name. The proto is the unicode string to the protocol name. Currently,
spdy/2
andspdy/3
are supported. The returned nonzero SPDY version can be passed as the version argument inSession
constructor.This function returns nonzero SPDY version if it succeeds, or 0.
Data Provider Objects¶
-
class
spdylay.
DataProvider
(source, read_cb)¶ This class represents the data source and the way to read a chunk of data from it. The source is expected to be the data source to read, but the application can freely pass any object including
None
. The read_cb is the callback function invoked when the library needs to read data. The data read will be sent as DATA frame.-
read_cb
(session, stream_id, length, read_ctrl, source)¶ The session is the
Session
object. The stream_id is the stream to send data. The source is the object passed as a source in DataProvider constructor. The implementation of this callback must read at most length bytes of data and return it as bytestring. When all data is read, assignREAD_EOF
toread_ctrl.flags
. If the application wants to postpone DATA frames, (e.g., asynchronous I/O, or reading data blocks for long time), it is achieved by returningERR_DEFERRED
without reading any data in this invocation. The library removes DATA frame from the outgoing queue temporarily. To move back deferred DATA frame to outgoing queue, callSession.resume_data()
. In case of error, there are 2 choices. RaisingTemporalCallbackFailureError
will close the stream by issuing RST_STREAM withINTERNAL_ERROR
. RaisingCallbackFailureError
will signal the entire session failure.
-
-
DataProvider.
source
¶
-
DataProvider.
read_cb
Control Frame Objects¶
-
class
spdylay.
CtrlFrame
¶ The base class of SPDY control frames.
-
version
¶ Version
-
frame_type
¶ Frame type. See Frame Types.
-
flags
¶ Flags. See Control Frame Flags.
-
length
¶ Frame payload length
-
The following frame classes inherit CtrlFrame
class.
Exceptions¶
-
class
spdylay.
EOFError
¶
-
class
spdylay.
CallbackFailureError
¶
-
class
spdylay.
TemporalCallbackFailureError
¶
-
class
spdylay.
InvalidArgumentError
¶
-
class
spdylay.
ZlibError
¶
-
class
spdylay.
UnsupportedVersionError
¶
-
class
spdylay.
StreamClosedError
¶
Error Codes¶
-
spdylay.
ERR_INVALID_ARGUMENT
¶
-
spdylay.
ERR_ZLIB
¶
-
spdylay.
ERR_UNSUPPORTED_VERSION
¶
-
spdylay.
ERR_WOULDBLOCK
¶
-
spdylay.
ERR_PROTO
¶
-
spdylay.
ERR_INVALID_FRAME
¶
-
spdylay.
ERR_EOF
¶
-
spdylay.
ERR_DEFERRED
¶
-
spdylay.
ERR_STREAM_ID_NOT_AVAILABLE
¶
-
spdylay.
ERR_STREAM_CLOSED
¶
-
spdylay.
ERR_STREAM_CLOSING
¶
-
spdylay.
ERR_STREAM_SHUT_WR
¶
-
spdylay.
ERR_INVALID_STREAM_ID
¶
-
spdylay.
ERR_INVALID_STREAM_STATE
¶
-
spdylay.
ERR_DEFERRED_DATA_EXIST
¶
-
spdylay.
ERR_SYN_STREAM_NOT_ALLOWED
¶
-
spdylay.
ERR_GOAWAY_ALREADY_SENT
¶
-
spdylay.
ERR_INVALID_HEADER_BLOCK
¶
-
spdylay.
ERR_INVALID_STATE
¶
-
spdylay.
ERR_GZIP
¶
-
spdylay.
ERR_TEMPORAL_CALLBACK_FAILURE
¶
Following error codes indicate fatal error.
-
spdylay.
ERR_FATAL
¶
-
spdylay.
ERR_NOMEM
¶
-
spdylay.
ERR_CALLBACK_FAILURE
¶
Frame Types¶
-
spdylay.
SYN_STREAM
¶
-
spdylay.
SYN_REPLY
¶
-
spdylay.
RST_STREAM
¶
-
spdylay.
SETTINGS
¶
-
spdylay.
NOOP
¶ Note that this was deprecated in SPDY/3.
-
spdylay.
PING
¶
-
spdylay.
GOAWAY
¶
-
spdylay.
HEADERS
¶
-
spdylay.
WINDOW_UPDATE
¶ This first appeared in SPDY/3.
-
spdylay.
CREDENTIAL
¶ This first appeared in SPDY/3.
Control Frame Flags¶
-
spdylay.
CTRL_FLAG_NONE
¶ Indicates no flags set.
-
spdylay.
CTRL_FLAG_FIN
¶
-
spdylay.
CTRL_FLAG_UNIDIRECTIONAL
¶
Stream Status Codes¶
-
spdylay.
OK
¶ This is not a valid status code for RST_STREAM. Don’t use this in
Session.submit_rst_stream()
.
-
spdylay.
PROTOCOL_ERROR
¶
-
spdylay.
INVALID_STREAM
¶
-
spdylay.
REFUSED_STREAM
¶
-
spdylay.
UNSUPPORTED_VERSION
¶
-
spdylay.
CANCEL
¶
-
spdylay.
INTERNAL_ERROR
¶
-
spdylay.
FLOW_CONTROL_ERROR
¶
Following status codes were introduced in SPDY/3.
-
spdylay.
STREAM_IN_USE
¶
-
spdylay.
STREAM_ALREADY_CLOSED
¶
-
spdylay.
INVALID_CREDENTIALS
¶
-
spdylay.
FRAME_TOO_LARGE
¶
GOAWAY Status Codes¶
-
spdylay.
GOAWAY_OK
¶
-
spdylay.
GOAWAY_PROTOCOL_ERROR
¶
-
spdylay.
GOAWAY_INTERNAL_ERROR
¶
SETTINGS IDs¶
-
spdylay.
SETTINGS_UPLOAD_BANDWIDTH
¶
-
spdylay.
SETTINGS_DOWNLOAD_BANDWIDTH
¶
-
spdylay.
SETTINGS_ROUND_TRIP_TIME
¶
-
spdylay.
SETTINGS_MAX_CONCURRENT_STREAMS
¶
-
spdylay.
SETTINGS_CURRENT_CWND
¶
-
spdylay.
SETTINGS_DOWNLOAD_RETRANS_RATE
¶
-
spdylay.
SETTINGS_INITIAL_WINDOW_SIZE
¶
-
spdylay.
SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE
¶
-
spdylay.
SETTINGS_MAX
¶
SETTINGS ID Flags¶
-
spdylay.
ID_FLAG_SETTINGS_NONE
¶
-
spdylay.
ID_FLAG_SETTINGS_PERSIST_VALUE
¶
-
spdylay.
ID_FLAG_SETTINGS_PERSISTED
¶
Simple SPDY Client¶
This module offers a simple SPDY client implementation. The function
urlfetch()
fetches given URLs. For each URL,
StreamHandlerClass is instantiated and its methods are called when
certain event occurs. The StreamHandlerClass must be a subclass of
BaseSPDYStreamHandler
.
-
spdylay.
urlfetch
(url_or_urls, StreamHandlerClass)¶ Opens URL and handles the response from the servers.
The url_or_urls is either one URL string or list of URL string. For each URL, StreamHandlerClass is instantiated and it handles the request to and response from the server. If successive URLs in url_or_urls list have same origin, they are processed in one SPDY session.
-
class
spdylay.
BaseSPDYStreamHandler
(url, fetcher)¶ This class handles one URL retrieval, which corresponds one SPDY stream. The url is the URL to fetch. The fetcher is a driver object to call methods of this object. For now it is opaque object. This class is intended to be subclassed by the application to add specific behavior.
BaseSPDYStreamHandler
has the following instance variables:-
url
¶ The URL for this stream.
-
stream_id
¶ The stream ID for this stream.
BaseSPDYStreamHandler
has the following methods:-
on_header
(nv)¶ Called when name/value pairs (headers) nv is received. This method may be overridden by subclasses. The default implementation does nothing.
-
on_data
(data)¶ Called when data is received. This method may be overridden by subclass. The default implementation does nothing.
-
on_close
(status_code)¶ Called when this stream is closed. The status_code indicates the reason of the closure. See Stream Status Codes. This method may be overridden by subclass. The default implementation does nothing.
-
The example follows:
#!/usr/bin/env python
# The example SPDY client. You need Python 3.3 or later because we
# use TLS NPN.
#
# Usage: spdyclient.py URL...
#
import sys
import spdylay
class MyStreamHandler(spdylay.BaseSPDYStreamHandler):
def on_header(self, nv):
sys.stdout.write('Stream#{}\n'.format(self.stream_id))
for k, v in nv:
sys.stdout.write('{}: {}\n'.format(k, v))
def on_data(self, data):
sys.stdout.write('Stream#{}\n'.format(self.stream_id))
sys.stdout.buffer.write(data)
def on_close(self, status_code):
sys.stdout.write('Stream#{} closed\n'.format(self.stream_id))
if __name__ == '__main__':
uris = sys.argv[1:]
spdylay.urlfetch(uris, MyStreamHandler)
Simple SPDY Server¶
This module offers a simple SPDY server implementation to ready for use with little additional code.
The ThreadedSPDYServer
is a socketserver.TCPServer
subclass. As the name of the class suggests, it is multi threaded.
It only supports SPDY connection and does not fallback to HTTP/1.1.
Since it uses TLS NPN extension, Python 3.3.0 or later is required.
-
class
spdylay.
ThreadedSPDYServer
(server_address, RequestHandlerCalss, cert_file, key_file)¶ This class builds on
TCPServer
class by passing server_address and RequestHandlerCalss. The request is handled by the instance of RequestHandlerCalss.
The ThreadedSPDYServer
requires a RequestHandlerCalss on
instantiation, which must be a subclass of
BaseSPDYRequestHandler
.
Most texts are copied (and modified) from http.server
documentation.
-
class
spdylay.
BaseSPDYRequestHandler
(request, client_address, server)¶ This class is used to handle the SPDY requests (streams) that arrive at the server. By itself, it cannot respond to any actual SPDY requests; it must be subclassed to handle each request method (e.g.
GET
orPOST
).BaseSPDYRequestHandler
provides a number of class and instance variables, and methods for use by subclasses.The handler will gather headers (name/value pairs in SPDY terms) and read POST data (if any), then call a method specific to the request type. The method name is constructed from the request. For example, for the request method
SPAM
, thedo_SPAM()
method will be called with no arguments. All of the relevant information is stored in instance variables of the handler. Subclasses should not need to override or extend the__init__()
method.Note
Currently, this implementation accepts request body only if method is POST and the request body will be stored in memory.
BaseSPDYRequestHandler
has the following instance variables:-
client_address
¶ Contains a tuple of the form
(host, port)
referring to the client’s address.
-
server
¶ Contains the server instance.
-
command
¶ Contains the command (request type, method). For example,
GET
.
-
path
¶ Contains the request path.
-
request_version
¶ Contains the version string from the request. For example,
HTTP/1.1
.
-
headers
¶ Contains the request headers. Each name/value pair is a tuple of the form
(name, value)
.
-
rfile
¶ Contains an input stream, positioned at the start of the optional input data. If there is no optional input data, it may be
None
.
-
wfile
¶ Contains the output stream for writing a response back to the client.
BaseSPDYRequestHandler
has the following class variables:-
server_version
¶ Specifies the server software version.
-
sys_version
¶ Contains the Python system version.
A
BaseSPDYRequestHandler
instance has the following methods:-
handle
()¶ Interacts client exchanging SPDY frames. When a request is completely received, it calls appropriate
do_*()
method. This method will handle multiple requests (streams) until SPDY session is over.
-
send_error
(code, message=None)¶ Send a complete error reply to the client The numeric code specifies the HTTP error code, with message as optional, more specific text. A complete set of headers is sent, followed by HTML text.
-
send_response
(code, message=None)¶ Adds a response code and, optionally, short message. This will be formatted as ‘:status’ response header field.
-
send_header
(keyword, value)¶ Adds the HTTP header. The keyword and value must be unicode strings and not
None
.
-
The example of BaseSPDYRequestHandler
and ThreadedSPDYServer
follows:
#!/usr/bin/env python
# The example SPDY server. Python 3.3 or later is required because TLS
# NPN is used in spdylay.ThreadedSPDYServer. Put private key and
# certificate file in the current working directory.
import spdylay
# private key file
KEY_FILE='server.key'
# certificate file
CERT_FILE='server.crt'
class MySPDYRequestHandler(spdylay.BaseSPDYRequestHandler):
def do_GET(self):
if self.path == '/notfound':
# Example code to return error
self.send_error(404)
return
self.send_response(200)
self.send_header('content-type', 'text/html; charset=UTF-8')
content = '''\
<html>
<head><title>SPDY FTW</title></head>
<body>
<h1>SPDY FTW</h1>
<p>The age of HTTP/1.1 is over. The time of SPDY has come.</p>
</body>
</html>'''.encode('UTF-8')
self.wfile.write(content)
if __name__ == "__main__":
HOST, PORT = "localhost", 3000
server = spdylay.ThreadedSPDYServer((HOST, PORT),
MySPDYRequestHandler,
cert_file=CERT_FILE,
key_file=KEY_FILE)
server.start()