def setup_environ(self): """ Setup the environ dictionary and add the `'ws4py.socket'` key. Its associated value is the real socket underlying socket. """ SimpleHandler.setup_environ(self) self.environ['ws4py.socket'] = get_connection(self.environ['wsgi.input'])
def setup_environ(self): """ Setup the environ dictionary and add the `'ws4py.socket'` key. Its associated value is the real socket underlying socket. """ SimpleHandler.setup_environ(self) self.environ['ws4py.socket'] = get_connection(self.environ['wsgi.input']) self.http_version = self.environ['SERVER_PROTOCOL'].rsplit('/')[-1]
def setup_environ(self): """ Setup the environ dictionary and add the `'ws4py.socket'` key. Its associated value is the real socket underlying socket. """ SimpleHandler.setup_environ(self) self.environ['ws4py.socket'] = get_connection( self.environ['wsgi.input'])
def __call__(self, environ, start_response): """ WSGI entry point """ # Upgrade header means websockets... upgrade_header = environ.get('HTTP_UPGRADE', '').lower() if upgrade_header: from ws4py.compat import get_connection environ['ws4py.socket'] = get_connection(environ['wsgi.input']) # This will make a websocket, hopefully! ret = self.wsapp(environ, start_response) if 'ws4py.websocket' in environ: import cothread cothread.Spawn(environ.pop('ws4py.websocket').run) return ret # Find path to file to server path_info = environ["PATH_INFO"] if not path_info: return self._not_found(start_response) elif path_info == "/": path_info = "/index.html" file_path = os.path.join(self.path, path_info[1:]) # If file does not exist, return 404 if not os.path.exists(file_path): return self._not_found(start_response) # Guess mimetype of file based on file extension import mimetypes mimetype = mimetypes.guess_type(file_path)[0] # If we can't guess mimetype, return a 403 Forbidden if mimetype is None: if file_path.endswith(".woff"): mimetype = "application/octet-stream" else: return self._forbidden(start_response) # Get size of file size = os.path.getsize(file_path) # Create headers and start response headers = [ ("Content-type", mimetype), ("Content-length", str(size)), ] start_response("200 OK", headers) # Send file return self._send_file(file_path, size)
def upgrade(self, protocols=None, extensions=None, version=WS_VERSION, handler_cls=WebSocket, heartbeat_freq=None): """ Performs the upgrade of the connection to the WebSocket protocol. The provided protocols may be a list of WebSocket protocols supported by the instance of the tool. When no list is provided and no protocol is either during the upgrade, then the protocol parameter is not taken into account. On the other hand, if the protocol from the handshake isn't part of the provided list, the upgrade fails immediatly. """ request = cherrypy.serving.request request.process_request_body = False ws_protocols = None ws_location = None ws_version = version ws_key = None ws_extensions = [] if request.method != 'GET': raise HandshakeError('HTTP method must be a GET') for key, expected_value in [('Upgrade', 'websocket'), ('Connection', 'upgrade')]: actual_value = request.headers.get(key, '').lower() if not actual_value: raise HandshakeError('Header %s is not defined' % key) if expected_value not in actual_value: raise HandshakeError('Illegal value for header %s: %s' % (key, actual_value)) version = request.headers.get('Sec-WebSocket-Version') supported_versions = ', '.join([str(v) for v in ws_version]) version_is_valid = False if version: try: version = int(version) except: pass else: version_is_valid = version in ws_version if not version_is_valid: cherrypy.response.headers[ 'Sec-WebSocket-Version'] = supported_versions raise HandshakeError('Unhandled or missing WebSocket version') key = request.headers.get('Sec-WebSocket-Key') if key: ws_key = base64.b64decode(key.encode('utf-8')) if len(ws_key) != 16: raise HandshakeError("WebSocket key's length is invalid") protocols = protocols or [] subprotocols = request.headers.get('Sec-WebSocket-Protocol') if subprotocols: ws_protocols = [] for s in subprotocols.split(','): s = s.strip() if s in protocols: ws_protocols.append(s) exts = extensions or [] extensions = request.headers.get('Sec-WebSocket-Extensions') if extensions: for ext in extensions.split(','): ext = ext.strip() if ext in exts: ws_extensions.append(ext) location = [] include_port = False if request.scheme == "https": location.append("wss://") include_port = request.local.port != 443 else: location.append("ws://") include_port = request.local.port != 80 location.append('localhost') if include_port: location.append(":%d" % request.local.port) location.append(request.path_info) if request.query_string != "": location.append("?%s" % request.query_string) ws_location = ''.join(location) response = cherrypy.serving.response response.stream = True response.status = '101 Switching Protocols' response.headers['Content-Type'] = 'text/plain' response.headers['Upgrade'] = 'websocket' response.headers['Connection'] = 'Upgrade' response.headers['Sec-WebSocket-Version'] = str(version) response.headers['Sec-WebSocket-Accept'] = base64.b64encode( sha1(key.encode('utf-8') + WS_KEY).digest()) if ws_protocols: response.headers['Sec-WebSocket-Protocol'] = ', '.join( ws_protocols) if ws_extensions: response.headers['Sec-WebSocket-Extensions'] = ','.join( ws_extensions) addr = (request.remote.ip, request.remote.port) ws_conn = get_connection(request.rfile.rfile) request.ws_handler = handler_cls(ws_conn, ws_protocols, ws_extensions, request.wsgi_environ.copy(), heartbeat_freq=heartbeat_freq)
def upgrade(self, protocols=None, extensions=None, version=WS_VERSION, handler_cls=WebSocket, heartbeat_freq=None): """ Performs the upgrade of the connection to the WebSocket protocol. The provided protocols may be a list of WebSocket protocols supported by the instance of the tool. When no list is provided and no protocol is either during the upgrade, then the protocol parameter is not taken into account. On the other hand, if the protocol from the handshake isn't part of the provided list, the upgrade fails immediatly. """ request = cherrypy.serving.request request.process_request_body = False ws_protocols = None ws_location = None ws_version = version ws_key = None ws_extensions = [] if request.method != 'GET': raise HandshakeError('HTTP method must be a GET') for key, expected_value in [('Upgrade', 'websocket'), ('Connection', 'upgrade')]: actual_value = request.headers.get(key, '').lower() if not actual_value: raise HandshakeError('Header %s is not defined' % key) if expected_value not in actual_value: raise HandshakeError('Illegal value for header %s: %s' % (key, actual_value)) version = request.headers.get('Sec-WebSocket-Version') supported_versions = ', '.join([str(v) for v in ws_version]) version_is_valid = False if version: try: version = int(version) except: pass else: version_is_valid = version in ws_version if not version_is_valid: cherrypy.response.headers['Sec-WebSocket-Version'] = supported_versions raise HandshakeError('Unhandled or missing WebSocket version') key = request.headers.get('Sec-WebSocket-Key') if key: ws_key = base64.b64decode(key.encode('utf-8')) if len(ws_key) != 16: raise HandshakeError("WebSocket key's length is invalid") protocols = protocols or [] subprotocols = request.headers.get('Sec-WebSocket-Protocol') if subprotocols: ws_protocols = [] for s in subprotocols.split(','): s = s.strip() if s in protocols: ws_protocols.append(s) exts = extensions or [] extensions = request.headers.get('Sec-WebSocket-Extensions') if extensions: for ext in extensions.split(','): ext = ext.strip() if ext in exts: ws_extensions.append(ext) location = [] include_port = False if request.scheme == "https": location.append("wss://") include_port = request.local.port != 443 else: location.append("ws://") include_port = request.local.port != 80 location.append('localhost') if include_port: location.append(":%d" % request.local.port) location.append(request.path_info) if request.query_string != "": location.append("?%s" % request.query_string) ws_location = ''.join(location) response = cherrypy.serving.response response.stream = True response.status = '101 Switching Protocols' response.headers['Content-Type'] = 'text/plain' response.headers['Upgrade'] = 'websocket' response.headers['Connection'] = 'Upgrade' response.headers['Sec-WebSocket-Version'] = str(version) response.headers['Sec-WebSocket-Accept'] = base64.b64encode(sha1(key.encode('utf-8') + WS_KEY).digest()) if ws_protocols: response.headers['Sec-WebSocket-Protocol'] = ', '.join(ws_protocols) if ws_extensions: response.headers['Sec-WebSocket-Extensions'] = ','.join(ws_extensions) addr = (request.remote.ip, request.remote.port) rfile = request.rfile.rfile if isinstance(rfile, KnownLengthRFile): rfile = rfile.rfile ws_conn = get_connection(rfile) request.ws_handler = handler_cls(ws_conn, ws_protocols, ws_extensions, request.wsgi_environ.copy(), heartbeat_freq=heartbeat_freq)