Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from xeross/HEAD
Update to use gevent-websocket instead of ws4py
- Loading branch information
Showing
4 changed files
with
7 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,96 +1,7 @@ | |||
import base64 | from bottle import request | ||
try: | |||
import ujson as json | |||
except ImportError: | |||
try: | |||
import simplejson as json | |||
except ImportError: | |||
try: | |||
import json | |||
except ImportError: | |||
json = None | |||
|
|||
from hashlib import sha1 | |||
|
|||
from bottle import request, HTTPError | |||
|
|||
from ws4py.exc import HandshakeError | |||
from ws4py import WS_KEY | |||
from ws4py.server.wsgi.middleware import WebSocketHandler | |||
|
|||
WS_VERSION = 8 | |||
|
|||
CLOSE_SOCKET = True | |||
|
|
||
def websocket(callback): | def websocket(callback): | ||
def wrapper(*args, **kwargs): | def wrapper(*args, **kwargs): | ||
try: | callback(request.environ.get('wsgi.websocket'), *args, **kwargs) | ||
if 'websocket' not in request.environ.get('upgrade.protocol', ''): | |||
raise HandshakeError("Upgrade protocol is not websocket") | |||
|
|||
if request.environ.get('REQUEST_METHOD') != 'GET': | |||
raise HandshakeError('Method is not GET') | |||
|
|||
key = request.environ.get('HTTP_SEC_WEBSOCKET_KEY') | |||
if key: | |||
ws_key = base64.b64decode(key) | |||
if len(ws_key) != 16: | |||
raise HandshakeError("WebSocket key's length is invalid") | |||
else: | |||
raise HandshakeError("Not a valid HyBi WebSocket request") | |||
|
|||
version = request.environ.get('HTTP_SEC_WEBSOCKET_VERSION') | |||
if version: | |||
if version != str(WS_VERSION): | |||
raise HandshakeError('Unsupported WebSocket version') | |||
request.environ['websocket.version'] = str(WS_VERSION) | |||
else: | |||
raise HandshakeError('WebSocket version required') | |||
except HandshakeError, e: | |||
raise HTTPError(code=400, output=e) | |||
|
|||
# Collect supported subprotocols | |||
protocols = [] | |||
subprotocols = request.environ.get('HTTP_SEC_WEBSOCKET_PROTOCOL') | |||
ws_protocols = [] | |||
if subprotocols: | |||
for s in subprotocols.split(','): | |||
s = s.strip() | |||
if s in protocols: | |||
ws_protocols.append(s) | |||
|
|||
# Collect supported extensions | |||
exts = [] | |||
ws_extensions = [] | |||
extensions = request.environ.get('HTTP_SEC_WEBSOCKET_EXTENSIONS') | |||
if extensions: | |||
for ext in extensions.split(','): | |||
ext = ext.strip() | |||
if ext in exts: | |||
ws_extensions.append(ext) | |||
|
|||
# Build and start the HTTP response | |||
headers = [ | |||
('Upgrade', 'websocket'), | |||
('Connection', 'Upgrade'), | |||
('Sec-WebSocket-Version', request.environ['websocket.version']), | |||
('Sec-WebSocket-Accept', base64.b64encode(sha1(key + WS_KEY).digest())), | |||
] | |||
if ws_protocols: | |||
headers.append(('Sec-WebSocket-Protocol', ', '.join(ws_protocols))) | |||
if ws_extensions: | |||
headers.append(('Sec-WebSocket-Extensions', ','.join(ws_extensions))) | |||
socket = request.environ.get('upgrade.socket') | |||
socket.send("HTTP/1.1 101 Switching Protocols\r\n") | |||
for k,v in headers: | |||
socket.send(': '.join([k,v]) + '\r\n') | |||
socket.send('\r\n') | |||
|
|
||
websocket = WebSocketHandler(socket, ws_protocols, ws_extensions, request.environ) | |||
if json: | |||
websocket.send_json = lambda msg: websocket.send(json.dumps(msg)) | |||
websocket.receive_json = lambda: json.loads(websocket.receive()) | |||
callback(websocket, *args, **kwargs) | |||
if CLOSE_SOCKET: | |||
websocket.close() | |||
return wrapper | return wrapper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,9 +1,7 @@ | |||
from bottle import ServerAdapter | from bottle import ServerAdapter | ||
from gevent import pywsgi, monkey, local | from gevent import pywsgi | ||
from ws4py.server.geventserver import UpgradableWSGIHandler | from geventwebsocket.handler import WebSocketHandler | ||
import threading | |||
|
|
||
class GeventWebSocketServer(ServerAdapter): | class GeventWebSocketServer(ServerAdapter): | ||
def run(self, handler): | def run(self, handler): | ||
if not threading.local is local.local: monkey.patch_all() | pywsgi.WSGIServer((self.host, self.port), handler, handler_class=WebSocketHandler).serve_forever() | ||
pywsgi.WSGIServer((self.host, self.port), handler, handler_class=UpgradableWSGIHandler).serve_forever() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,2 +1,2 @@ | |||
gevent | gevent | ||
git+https://github.com/progrium/WebSocket-for-Python.git | gevent-websocket |