===============================================================================
asynwsgi: A light weight, asynchronous, pep-333/WSGI compatible http server
===============================================================================
.. include:: pkg-info.rst

.. contents::

wsgi implementation status
~~~~~~~~~~~~~~~~~~~~~~~~~~

Certain aspects of the wsgi spec implementation may be neither complete or
correct. Development is currently focused on identifying how performance of
async servers is affected by aspects of the wsgi spec.


``wsgi.input``: 
    * For Transfer-Encoding:chunks: read, readline etc are NOT SUPPORTED. The
      only means to process the input is via the __iter__ method. See
      ``asynwsgi.wsgiservice.server:wsgi_file_uploader`` for an example. The 
      yield pattern for __iter__ is also somewhat specialised. It is::

        [chunksz, datafirst] [data]* [chunksz, datafirst] [data]* ... [0 '']

      This pattern enables the server to deal with chunk boundaries on behalf of 
      your application with out incurring excessive buffering overhead.

      The iterator will raise StopIteration *after* it has yielded the
      terminating chunk. The future plan is to incorporate trailer headers into
      this yield pattern but presently any trailer headers are silently droped
      on the floor (this is actualy RFC 2616 compliant although not very
      friendly).

      Your application iterable is GUARANTEED only to be resumed if input.next()
      has some data ready (either [chunksz, datafirst] or some/all of [data]*).
      If on a subsequent iteration the server detects EAGAIN/EWOULDBLOCK then
      input.next() will return ``wsgi.input_sentinel``. If your application 
      sees this value it should simply yield it back to the server. So the 
      simplest idiom is::

          uploaded = cStringIO.StringIO()
          content_length = 0
          for v in iter(environ['wsgi.input']):
              if d is environ['wsgi.input_sentinel']):
                  yield d
                  continue
              if not isinstance(d, str):
                  chunksz, d = d
                  content_length += chunksz
              uploaded.write(d)
          assert len(uploaded.getvalue()) == content_length

      Note: wsgiservice.server has an example application interable that handles
      POST with transfercoding:chunks and you can test this using::

          python -m asynwsg.bench.http_processing --synthesize-post=NCHUNKS\
          --chunksz=NBYTES http://localhost:8080/uploader/

    * POST suport where Transfer-Encoding header is absent or is set to 'none'
      At present the server collects all the data into a cStringIO.StringIO 
      instance and does not invoke the application until *all* input has been
      collected. (AND this is not particularly well tested at present)
