Skip to content

Commit

Permalink
a bit more doc
Browse files Browse the repository at this point in the history
  • Loading branch information
Lawouach committed Feb 23, 2012
1 parent 49ee697 commit ce696c6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 10 deletions.
18 changes: 12 additions & 6 deletions ws4py/server/geventserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class UpgradableWSGIHandler(gevent.pywsgi.WSGIHandler):
If an HTTP request comes in that includes the Upgrade header, it will add
to the environment two items:
`upgrade.protocol`
``upgrade.protocol` `
The protocol to upgrade to. Checking for this lets you know the request
wants to be upgraded and the WSGI server supports this interface.
`upgrade.socket`
``upgrade.socket``
The raw Python socket object for the connection. From this you can do any
upgrade negotiation and hand it off to the proper protocol handler.
Expand All @@ -34,14 +34,20 @@ class UpgradableWSGIHandler(gevent.pywsgi.WSGIHandler):
To use this handler with gevent.pywsgi.WSGIServer, you can pass it to the
constructor:
server = WSGIServer(('127.0.0.1', 80), app,
handler_class=UpgradableWSGIHandler)
.. code-block:: python
:linenos:
server = WSGIServer(('127.0.0.1', 80), app,
handler_class=UpgradableWSGIHandler)
Alternatively, you can specify it as a class variable for a WSGIServer
subclass:
class UpgradableWSGIServer(gevent.pywsgi.WSGIServer):
handler_class = UpgradableWSGIHandler
.. code-block:: python
:linenos:
class UpgradableWSGIServer(gevent.pywsgi.WSGIServer):
handler_class = UpgradableWSGIHandler
"""
def run_application(self):
Expand Down
36 changes: 32 additions & 4 deletions ws4py/server/wsgi/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,37 @@
from ws4py.websocket import WebSocket

class WebSocketUpgradeMiddleware(object):
"""WSGI middleware for handling WebSocket upgrades"""

def __init__(self, app, fallback_app=None, protocols=None, extensions=None,
websocket_class=WebSocket):
"""
WSGI middleware that performs the WebSocket upgrade handshake.
.. code-block:: python
:linenos:
def ws_handler(websocket):
...
app = WebSocketUpgradeMiddleware(ws_handler)
If the handshake succeeds, it calls ``app`` with an instance of
``websocket_class`` with a copy of the environ dictionary.
If an error occurs and ``fallback_app`` is provided, it must be a
WSGI application which will be called. Otherwise it returns a
simple error through the inner ``start_response``.
One interesting aspect is that wsgiref fails with this middleware
due to the ``Upgrade`` hop-by-hop header which is not allowed.
Make sure that your server does not close the underlying socket for you
since it would close the whole WebSocket connection as well.
You may provide your own representation of the socket by setting
the environ key: ``'upgrade.socket'``. Otherwise, ``'wsgi.input'._sock``
will be used.
"""
self.app = app
self.fallback_app = fallback_app
self.protocols = protocols
Expand All @@ -24,7 +51,7 @@ def __init__(self, app, fallback_app=None, protocols=None, extensions=None,
def __call__(self, environ, start_response):
# Initial handshake validation
try:
if 'websocket' not in environ.get('upgrade.protocol', '').lower():
if 'websocket' not in environ.get('upgrade.protocol', environ.get('HTTP_UPGRADE', '')).lower():
raise HandshakeError("Upgrade protocol is not websocket")

if environ.get('REQUEST_METHOD') != 'GET':
Expand Down Expand Up @@ -86,7 +113,8 @@ def __call__(self, environ, start_response):

start_response("101 Web Socket Hybi Handshake", headers)

return self.app(self.websocket_class(environ.get('upgrade.socket'),
return self.app(self.websocket_class(environ.get('upgrade.socket',
environ.get('wsgi.input')._sock),
ws_protocols,
ws_extensions,
environ.copy()))

0 comments on commit ce696c6

Please sign in to comment.