python.rst 32.3 KB
Newer Older
1 2
Python-spdylay - Spdylay Python Extension Module
================================================
3 4 5

.. py:module:: spdylay

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
6 7
Python-spdylay is the Python extension module of Spdylay SPDY C
library.
8 9 10 11 12 13 14 15 16 17 18 19

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

20
Session Objects
21 22
---------------

23
.. py:class:: 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)
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91

    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:

    .. py:data:: CLIENT

        Indicates client.

    .. py:data:: SERVER

        Indicates server.

    The *version* specifies SPDY protocol version. Use of the following:

    .. py:data:: PROTO_SPDY2

        Indicates SPDY/2.

    .. py:data:: PROTO_SPDY3

        Indicates SPDY/3.

    The *user_data* specifies opaque object tied to this object. It
    can be accessed through :py:attr:`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:

    .. py:function:: recv_cb(session, length)

        The *session* is the :py:class:`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 or ``None``. If it gets EOF before it reads any
        single byte, it must raise :py:class:`EOFError`. For other
        errors, it must raise :py:class:`CallbackFailureError`.

    The *send_cb* specifies callback function (callable) invoked when
    session wants to send data to the remote peer. The signature of
    this callback is:

    .. py:function:: send_cb(session, data)

        The *session* is the :py:class:`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 or ``None``. For other errors, it must return
        :py:class:`CallbackFailureError`.

    The *on_ctrl_recv_cb* specifies callback function (callable)
    invoked when a control frame is received.

    .. py:function:: on_ctrl_recv_cb(session, frame)

        The *session* is the :py:class:`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.

92 93 94 95 96 97 98 99 100 101 102 103 104 105
    The *on_invalid_ctrl_recv_cb* specifies callback function
    (callable) invoked when an invalid control frame is received.

    .. py:function:: on_invalid_ctrl_recv_cb(session, frame, status_code)

        The *session* is the :py:class:`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.

106 107 108 109 110 111 112 113 114 115 116 117 118 119
    The *on_data_chunk_recv_cb* specifies callback function (callable)
    invoked when a chunk of data in DATA frame is received.

    .. py:function:: on_data_chunk_recv_cb(session, flags, stream_id, data)

        The *session* is the :py:class:`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 use :py:func:`on_data_recv_cb` to know all
        data frames are received. The *data* is the bytestring of
        received data.

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    The *on_data_recv_cb* specifies callback function (callable)
    invoked when DATA frame is received.

    .. py:function:: on_data_recv_cb(session, flags, stream_id, length)

        The actual data it contains are received by
        :py:func:`on_data_chunk_recv_cb()`.

    The *before_ctrl_send_cb* specifies callback function (callable)
    invoked before the control frame is sent.

    .. py:function:: before_ctrl_send_cb(session, frame)

        The *session* is the :py:class:`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.

    .. py:function:: on_ctrl_send_cb(session, frame)

        The *session* is the :py:class:`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.

    .. py:function:: on_ctrl_not_send_cb(session, frame, error_code)

        The *session* is the :py:class:`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.

    .. py:function:: on_data_send_cb(session, flags, stream_id, length)

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
    The *on_stream_close_cb* specifies callback function (callable)
    invoked when the stream is closed.

    .. py:function:: on_stream_close_cb(session, stream_id, status_code)

        The *session* is the :py:class:`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 in :py:meth:`submit_request()` or
        :py:meth:`submit_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.

    .. py:function:: on_request_recv_cb(session, stream_id)

        The *session* is the :py:class:`Session` object invoking the
        callback. The *stream_id* indicates the stream ID.

192 193 194 195 196 197 198 199 200 201 202
    The *on_ctrl_recv_parse_error_cb* specifies callback function
    (callable) invoked when the received control frame octets could
    not be parsed correctly.

    .. py:function:: 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.
203

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
    The *on_unknown_ctrl_recv_cb* specifies callback function
    (callable) invoked when the received control frame type is
    unknown.

    .. py:function:: 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 :py:class:`InvalidArgumentError` will be raised if the given
    argument is invalid.  The :py:class:`UnsupportedVersionError` will
    be raised if the *version* is not supported. The
    :py:class:`ZlibError` will be raised if initialization of zlib
    failed.
219

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
.. py:attribute:: Session.user_data

    The object passed in the constructor as *user_data* argument.
    This attribute is read-only.

.. py:method:: 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 :py:func:`send_cb` returns 0 or ``None`` or the
    outbound queue becomes empty. This method calls several callback
    functions which are passed when initializing the session.  See
    :func:`spdylay_session_send` about the callback functions invoked
    from this method.

236 237 238
    The :py:class:`CallbackFailureError` will be raised if the
    callback function failed.

239 240 241 242 243 244 245 246 247 248 249 250 251
.. py:method:: Session.recv(data=None)

    Receives frames from the remote peer.  This method receives as
    many frames as possible until the user callback :py:func:`recv_cb`
    returns empty bytestring or ``None``. This function calls several
    callback functions which are passed when initializing the session.
    See :func:`spdylay_session_recv` about the callback functions
    invoked from this method. If data is ``None``, this method will
    invoke :py:func:`recv_cb` callback function to receive incoming
    data.  If data is not ``None``, it must be a bytestring and this
    method uses it as the incoming data and does not call
    :py:func:`recv_cb` callback function.

252 253 254 255
    The :py:class:`EOFError` will be raised if the remote peer did
    shutdown on the connection. The :py:class:`CallbackFailureError`
    will be raised if the callback function failed.

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
.. py:method:: Session.resume_data(stream_id)

    Puts back previously deferred DATA frame in the stream *stream_id*
    to the outbound queue.

    The :py:class:`InvalidArgumentError` will be raised if the stream
    does not exist or no deferred data exist.

.. py:method:: Session.want_read()

    Returns ``True`` if session wants to receive data from the
    remote peer.

    If both :py:meth:`want_read()` and :py:meth:`want_write()` return
    ``False``, the application should drop the connection.

.. py:method:: Session.want_write()

    Returns ``True`` if session wants to send data to the remote peer.

    If both :py:meth:`want_read()` and :py:meth:`want_write()` return
    ``False``, the application should drop the connection.

.. py:method:: Session.get_stream_user_data(stream_id)

    Returns stream_user_data for the stream *stream_id*. The
    stream_user_data is provided by :py:meth:`submit_request()` or
    :py:meth:`submit_syn_stream()`. If the stream is initiated by the
    remote endpoint, stream_user_data is always ``None``. If the
    stream is initiated by the local endpoint and ``None`` is given in
    :py:meth:`submit_request()` or :py:meth:`submit_syn_stream()`,
    then this function returns ``None``. If the stream does not exist,
    this function returns ``None``.

.. py:method:: Session.get_outbound_queue_size()

    Returns the number of frames in the outbound queue. This does not
    include the deferred DATA frames.

.. py:method:: Session.get_pri_lowest()

    Returns lowest priority value for the session.

.. py:method:: Session.fail_session(status_code)

    Submits GOAWAY frame. The status code *status_code* is ignored if
    the protocol version is :py:const:`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 :py:meth:`submit_goaway()` instead.

.. py:method:: 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. Use :py:meth:`get_pri_lowest()` to know the lowest
    priority value for this session.

316
    The *nv* is a list containing the name/value pairs.  The each
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
317 318
    element is a pair of unicode strings: name and value (e.g.,
    ``(u'host', u'localhost')``).
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347

    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
    :py:const:`PROTO_SPDY2`, the above names are translated to
    ``method``, ``scheme``, ``url``, ``version`` and ``host``
    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
348 349 350 351 352 353 354 355
    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.
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372

    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 :py:meth:`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
    :py:func:`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, :py:meth:`get_stream_user_data()` can be used to get
    stream_user_data to identify which SYN_STREAM we are processing.

    The :py:class:`InvalidArgumentError` will be raised if the *pri*
373
    is invalid; or the *nv* includes empty name or ``None`` value.
374 375 376 377 378 379

.. py:method:: 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*.

380
    The *nv* is a list containing the name/value pairs.  The each
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
381 382
    element is a pair of unicode strings: name and value (e.g.,
    ``(u'host', u'localhost')``).
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398

    The *nv* must include following name/value pairs:

    ``:status``
        HTTP status code (e.g., ``200`` or ``200 OK``)
    ``:version``
        HTTP response version (e.g., ``HTTP/1.1``)

    If the session is initialized with the version
    :py:const:`PROTO_SPDY2`, the above names are translated to
    ``status`` and ``version`` 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
399 400 401 402 403 404 405 406
    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.
407

408 409 410 411 412 413 414 415 416 417 418 419 420 421
    The :py:class:`InvalidArgumentError` will be raised if the *nv*
    includes empty name or ``None`` value.

.. py:method:: Session.submit_syn_stream(flags, assoc_stream_id, pri, nv, stream_user_data)

    Submits SYN_STREAM frame. The *flags* is bitwise OR of the
    following values:

    * :py:const:`CTRL_FLAG_FIN`
    * :py:const:`CTRL_FLAG_UNIDIRECTIONAL`

    If *flags* includes :py:const:`CTRL_FLAG_FIN`, this frame has
    FLAG_FIN flag set.

422 423 424
    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.
425 426 427 428 429 430

    The *pri* is priority of this request. ``0`` is the highest
    priority value. Use :py:meth:`get_pri_lowest()` to know the lowest
    priority value for this session.

    The *nv* is a list containing the name/value pairs.  The each
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
431 432
    element is a pair of unicode strings: name and value (e.g.,
    ``(u'host', u'localhost')``).
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461

    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 :py:meth:`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, :py:meth:`submit_request()` is useful.

    The :py:class:`InvalidArgumentError` will be raised if the *pri*
    is invalid; or the *assoc_stream_id* is invalid; or the *nv*
    includes empty name or ``None`` value.

.. py:method:: Session.submit_syn_reply(flags, stream_id, nv)

    Submits SYN_REPLY 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
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
462 463
    element is a pair of unicode strings: name and value (e.g.,
    ``(u'host', u'localhost')``).
464 465 466 467 468 469

    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.

470 471 472 473 474 475 476 477 478 479 480 481 482 483
.. 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
Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
484 485
    element is a pair of unicode strings: name and value (e.g.,
    ``(u'host', u'localhost')``).
486 487 488 489 490 491

    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.

492 493 494 495 496 497 498 499 500 501 502 503 504 505
.. 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.

506 507 508 509 510 511
.. py:method:: 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.

512 513 514 515
.. py:method:: Session.submit_ping()

    Submits PING frame.

516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
.. py:method:: Session.submit_goaway(status_code)

    Submits GOAWAY frame. The status code *status_code* is ignored if
    the protocol version is :py:const:`PROTO_SPDY2`. See `GOAWAY
    Status Codes`_ for available status codes.

.. py:method:: 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 :py:class:`InvalidArgumentError` will be raised if the *iv*
    contains duplicate settings ID or invalid value.

534 535 536 537 538 539 540 541 542 543 544
.. py:method:: 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 window
    ``size <= (1 << 31)-1``.

    The :py:class:`InvalidArgumentError` will be raised if the
    *delta_window_size* is 0 or negative. The
    :py:class:`StreamClosedError` will be raised if the stream is
    already closed or does not exist.
545

546 547 548 549 550 551 552 553 554 555 556 557 558 559
Helper Functions
----------------

.. py:function:: 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`` and ``spdy/3`` are supported.  The
    returned nonzero SPDY version can be passed as the version
    argument in :py:class:`Session` constructor.

    This function returns nonzero SPDY version if it succeeds, or 0.


560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
Data Provider Objects
---------------------

.. py:class:: 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.

    .. py:function:: read_cb(session, stream_id, length, read_ctrl, source)

        The *session* is the :py:class:`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, assign :py:const:`READ_EOF` to ``read_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 returning :py:const:`ERR_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, call
        :py:meth:`Session.resume_data()`. In case of error, there are
        2 choices. Raising :py:class:`TemporalCallbackFailureError`
        will close the stream by issuing RST_STREAM with
        :py:const:`INTERNAL_ERROR`. Raising
        :py:class:`CallbackFailureError` will signal the entire
        session failure.

.. py:attribute:: DataProvider.source

.. py:attribute:: DataProvider.read_cb

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
Control Frame Objects
---------------------

.. py:class:: CtrlFrame

    The base class of SPDY control frames.

    .. py:attribute:: version

        Version

    .. py:attribute:: frame_type

        Frame type. See `Frame Types`_.

    .. py:attribute:: flags

        Flags. See `Control Frame Flags`_.

    .. py:attribute:: length

        Frame payload length

The following frame classes inherit :py:class:`CtrlFrame` class.

.. py:class:: SynStreamFrame

    .. py:attribute:: stream_id

        Stream ID

    .. py:attribute:: assoc_stream_id

        Associated-To-Stream-ID

    .. py:attribute:: pri

        Priority

    .. py:attribute:: slot

        Credential slot

    .. py:attribute:: nv

        List of name/value pair.

.. py:class:: SynReplyFrame

    .. py:attribute:: stream_id

        Stream ID

    .. py:attribute:: nv

        List of name/value pair.

.. py:class:: HeadersFrame

    .. py:attribute:: stream_id

        Stream ID

    .. py:attribute:: nv

        List of name/value pair.

.. py:class:: RstStreamFrame


    .. py:attribute:: stream_id

        Stream ID

    .. py:attribute:: status_code

        Status code

.. py:class:: SettingsFrame

    .. py:attribute:: iv

        List of tuple ``(settings_id, flags, value)``

.. py:class:: PingFrame

    .. py:attribute:: unique_id

        Unique ID

.. py:class:: GoawayFrame

    .. py:attribute:: last_good_stream_id

        Last good stream ID

    .. py:attribute:: status_code

        Status code

.. py:class:: WindowUpdateFrame

    .. py:attribute:: stream_id

        Stream ID

    .. py:attribute:: delta_window_size

        Delta window size

Exceptions
----------

.. py:class:: EOFError

.. py:class:: CallbackFailureError

.. py:class:: TemporalCallbackFailureError

.. py:class:: InvalidArgumentError

.. py:class:: ZlibError

.. py:class:: UnsupportedVersionError

.. py:class:: StreamClosedError

724 725 726 727 728
Read Callback Flags
-------------------

.. py:data:: READ_EOF

729 730
Error Codes
-----------
731

732 733 734 735 736 737 738
.. py:data:: ERR_INVALID_ARGUMENT
.. py:data:: ERR_ZLIB
.. py:data:: ERR_UNSUPPORTED_VERSION
.. py:data:: ERR_WOULDBLOCK
.. py:data:: ERR_PROTO
.. py:data:: ERR_INVALID_FRAME
.. py:data:: ERR_EOF
739
.. py:data:: ERR_DEFERRED
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
.. py:data:: ERR_STREAM_ID_NOT_AVAILABLE
.. py:data:: ERR_STREAM_CLOSED
.. py:data:: ERR_STREAM_CLOSING
.. py:data:: ERR_STREAM_SHUT_WR
.. py:data:: ERR_INVALID_STREAM_ID
.. py:data:: ERR_INVALID_STREAM_STATE
.. py:data:: ERR_DEFERRED_DATA_EXIST
.. py:data:: ERR_SYN_STREAM_NOT_ALLOWED
.. py:data:: ERR_GOAWAY_ALREADY_SENT
.. py:data:: ERR_INVALID_HEADER_BLOCK
.. py:data:: ERR_INVALID_STATE
.. py:data:: ERR_GZIP
.. py:data:: ERR_TEMPORAL_CALLBACK_FAILURE

Following error codes indicate fatal error.

.. py:data:: ERR_FATAL
.. py:data:: ERR_NOMEM
.. py:data:: ERR_CALLBACK_FAILURE
759

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
Frame Types
-----------

.. py:data:: SYN_STREAM

.. py:data:: SYN_REPLY

.. py:data:: RST_STREAM

.. py:data:: SETTINGS

.. py:data:: NOOP

   Note that this was deprecated in SPDY/3.

.. py:data:: PING

.. py:data:: GOAWAY

.. py:data:: HEADERS

.. py:data:: WINDOW_UPDATE

   This first appeared in SPDY/3.

.. py:data:: CREDENTIAL

   This first appeared in SPDY/3.

789 790 791 792 793 794 795 796 797 798 799
Control Frame Flags
-------------------

.. py:data:: CTRL_FLAG_NONE

   Indicates no flags set.

.. py:data:: CTRL_FLAG_FIN

.. py:data:: CTRL_FLAG_UNIDIRECTIONAL

800 801 802 803 804
Stream Status Codes
-------------------

.. py:data:: OK

805 806 807
   This is not a valid status code for RST_STREAM. Don't use this in
   :py:meth:`Session.submit_rst_stream()`.

808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
.. py:data:: PROTOCOL_ERROR

.. py:data:: INVALID_STREAM

.. py:data:: REFUSED_STREAM

.. py:data:: UNSUPPORTED_VERSION

.. py:data:: CANCEL

.. py:data:: INTERNAL_ERROR

.. py:data:: FLOW_CONTROL_ERROR

Following status codes were introduced in SPDY/3.

.. py:data:: STREAM_IN_USE

.. py:data:: STREAM_ALREADY_CLOSED

.. py:data:: INVALID_CREDENTIALS

.. py:data:: FRAME_TOO_LARGE
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877

GOAWAY Status Codes
-------------------

.. py:data:: GOAWAY_OK

.. py:data:: GOAWAY_PROTOCOL_ERROR

.. py:data:: GOAWAY_INTERNAL_ERROR

SETTINGS Frame Flags
--------------------

.. py:data:: FLAG_SETTINGS_NONE

.. py:data:: FLAG_SETTINGS_CLEAR_SETTINGS

SETTINGS IDs
------------

.. py:data:: SETTINGS_UPLOAD_BANDWIDTH

.. py:data:: SETTINGS_DOWNLOAD_BANDWIDTH

.. py:data:: SETTINGS_ROUND_TRIP_TIME

.. py:data:: SETTINGS_MAX_CONCURRENT_STREAMS

.. py:data:: SETTINGS_CURRENT_CWND

.. py:data:: SETTINGS_DOWNLOAD_RETRANS_RATE

.. py:data:: SETTINGS_INITIAL_WINDOW_SIZE

.. py:data:: SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE

.. py:data::  SETTINGS_MAX

SETTINGS ID Flags
-----------------

.. py:data:: ID_FLAG_SETTINGS_NONE

.. py:data:: ID_FLAG_SETTINGS_PERSIST_VALUE

.. py:data:: ID_FLAG_SETTINGS_PERSISTED

Tatsuhiro Tsujikawa's avatar
Tatsuhiro Tsujikawa committed
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
Simple SPDY Server
------------------

This module offers a simple SPDY server implementation to ready for
use with little additional code.

The :py:class:`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.

.. py:class:: 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 :py:class:`ThreadedSPDYServer` requires a *RequestHandlerCalss* on
instantiation, which must be a subclass of
:py:class:`BaseSPDYRequestHandler`.

Most texts are copied (and modified) from ``http.server``
documentation.

.. py:class:: 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`` or ``POST``). ``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``, the ``do_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:

    .. py:attribute:: client_address

        Contains a tuple of the form ``(host, port)`` referring to the
        client's address.

    .. py:attribute:: server

        Contains the server instance.

    .. py:attribute:: command

        Contains the command (request type, method). For example,
        ``GET``.

    .. py:attribute:: path

        Contains the request path.

    .. py:attribute:: request_version

        Contains the version string from the request. For example,
        ``HTTP/1.1``.

    .. py:attribute:: headers

        Contains the request headers. Each name/value pair is a tuple
        of the form ``(name, value)``.

    .. py:attribute:: 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``.

    .. py:attribute:: wfile

        Contains the output stream for writing a response back to the
        client.

    ``BaseSPDYRequestHandler`` has the following class variables:

    .. py:attribute:: server_version

        Specifies the server software version.

    .. py:attribute:: sys_version

        Contains the Python system version.

    A ``BaseSPDYRequestHandler`` instance has the following methods:

    .. py:method:: 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.

    .. py:method:: 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.

    .. py:method:: send_response(code, message=None)

        Adds a response code and, optionally, short message.
        This will be formatted as ':status' response header field.

    .. py:method:: 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:

.. literalinclude:: ../python/spdyserv.py
    :language: python