def test_get_stack_trace(self): self.assertEqual('None\n', util.get_stack_trace()) try: a = 1 / 0 # Intentionally raise exception. except Exception: trace = util.get_stack_trace() self.failUnless(trace.startswith('Traceback')) self.failUnless(trace.find('ZeroDivisionError') != -1)
def parse_request(self): """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request. Return True to continue processing for HTTP(S), False otherwise. """ logging.info('standalone::parse_request') result = CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self) if result: try: logging.info('standalone::do_handshake') if not self._handshaker._request.headers_in.get('Upgrade') : logging.debug('standalone: Handling normal HTTP/HTTPS request') return True else: d = draft75.Handshaker(self._handshaker._request, self._handshaker._dispatcher) headers_in = self._handshaker._request.headers_in if headers_in.get('Upgrade') != 'WebSocket': raise HandshakeError('Exception 1') if headers_in.get('Connection') != 'Upgrade': raise HandshakeError('Exception 2') if not headers_in.get('Host'): raise HandshakeError('Exception 3') if not headers_in.get('Origin'): raise HandshakeError('Exception 4') d._set_resource() d._set_origin() d._set_location() d._set_protocol() d._dispatcher.do_extra_handshake(self._handshaker._request) d._send_handshake() try: self._dispatcher.transfer_data(self._request) except Exception, e: # Catch exception in transfer_data. # In this case, handshake has been successful, so just log # the exception and return False. logging.info('mod_pywebsocket: %s' % e) logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) return False except handshake.HandshakeError, e: # Handshake for ws(s) failed. Assume http(s). logging.info('mod_pywebsocket: %s' % e) logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) return True
def do_extra_handshake(self, request): """Do extra checking in WebSocket handshake. Select a handler based on request.uri and call its web_socket_do_extra_handshake function. Args: request: mod_python request. Raises: DispatchException: when handler was not found AbortedByUserException: when user handler abort connection HandshakeException: when opening handshake failed """ handler_suite = self.get_handler_suite(request.ws_resource) if handler_suite is None: raise DispatchException('No handler for: %r' % request.ws_resource) do_extra_handshake_ = handler_suite.do_extra_handshake try: do_extra_handshake_(request) except handshake.AbortedByUserException as e: # Re-raise to tell the caller of this function to finish this # connection without sending any error. self._logger.debug('%s', util.get_stack_trace()) raise except Exception as e: util.prepend_message_to_exception( '%s raised exception for %s: ' % ( _DO_EXTRA_HANDSHAKE_HANDLER_NAME, request.ws_resource), e) raise handshake.HandshakeException(e, common.HTTP_STATUS_FORBIDDEN)
def transfer_data(self, request): """Let a handler transfer_data with a WebSocket client. Select a handler based on request.ws_resource and call its web_socket_transfer_data function. Args: request: mod_python request. Raises: DispatchException: when handler was not found AbortedByUserException: when user handler abort connection """ # TODO(tyoshino): Terminate underlying TCP connection if possible. try: if mux.use_mux(request): mux.start(request, self) else: handler_suite = self.get_handler_suite(request.ws_resource) if handler_suite is None: raise DispatchException('No handler for: %r' % request.ws_resource) transfer_data_ = handler_suite.transfer_data transfer_data_(request) if not request.server_terminated: request.ws_stream.close_connection() # Catch non-critical exceptions the handler didn't handle. except handshake.AbortedByUserException, e: self._logger.debug('%s', util.get_stack_trace()) raise
def run(self): #Based on mod_pywebsocket/standalone.py main function #Start the queue tracker self.queuetracker = _ChopQueueTracker() self.queuetracker.start() self.options.queuetracker = self.queuetracker self.choplibshell = _ChopLibShell(self.queuetracker) self.choplibshell.start() self.options.choplibshell = self.choplibshell _configure_logging(self.options) os.chdir(self.options.document_root) self.options.cgi_directories = [] self.options.is_executable_method = None try: if self.options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(self.options.thread_monitor_interval_in_sec).start() self.server = ChopWebSocketServer(self.options) self.server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace())
def _source_handler_file(handler_definition): """Source a handler definition string. Args: handler_definition: a string containing Python statements that define handler functions. """ global_dic = {} try: exec handler_definition in global_dic except Exception: raise DispatchException('Error in sourcing handler:' + util.get_stack_trace()) passive_closing_handshake_handler = None try: passive_closing_handshake_handler = _extract_handler( global_dic, _PASSIVE_CLOSING_HANDSHAKE_HANDLER_NAME) except Exception: passive_closing_handshake_handler = ( _default_passive_closing_handshake_handler) return _HandlerSuite( _extract_handler(global_dic, _DO_EXTRA_HANDSHAKE_HANDLER_NAME), _extract_handler(global_dic, _TRANSFER_DATA_HANDLER_NAME), passive_closing_handshake_handler)
def do_extra_handshake(self, request): """Do extra checking in WebSocket handshake. Select a handler based on request.uri and call its web_socket_do_extra_handshake function. Args: request: mod_python request. Raises: DispatchException: when handler was not found AbortedByUserException: when user handler abort connection HandshakeException: when opening handshake failed """ handler_suite = self.get_handler_suite(request.ws_resource) if handler_suite is None: raise DispatchException('No handler for: %r' % request.ws_resource) do_extra_handshake_ = handler_suite.do_extra_handshake try: do_extra_handshake_(request) except handshake.AbortedByUserException, e: # Re-raise to tell the caller of this function to finish this # connection without sending any error. self._logger.debug('%s', util.get_stack_trace()) raise
def handle_error(self, rquest, client_address): """Override SocketServer.handle_error.""" self._logger.error( 'Exception in processing request from: %r\n%s', client_address, util.get_stack_trace())
def handle_error(self, request, client_address): """Override SocketServer.handle_error.""" self._logger.error( 'Exception in processing request from: %r\n%s', client_address, util.get_stack_trace())
def run(self): #Based on mod_pywebsocket/standalone.py main function #Start the queue tracker self.queuetracker = _ChopQueueTracker() self.queuetracker.start() self.options.queuetracker = self.queuetracker self.choplibshell = _ChopLibShell(self.queuetracker) self.choplibshell.start() self.options.choplibshell = self.choplibshell _configure_logging(self.options) os.chdir(self.options.document_root) self.options.cgi_directories = [] self.options.is_executable_method = None try: if self.options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor( self.options.thread_monitor_interval_in_sec).start() self.server = ChopWebSocketServer(self.options) self.server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace())
def handle_error(self, request, client_address): """ Override SocketServer.handle_error. """ self._logger.error( "Exception in processing request from: {0}\n{1}".format( client_address, util.get_stack_trace()))
def transfer_data(self, request): """Let a handler transfer_data with a WebSocket client. Select a handler based on request.ws_resource and call its web_socket_transfer_data function. Args: request: mod_python request. Raises: DispatchException: when handler was not found AbortedByUserException: when user handler abort connection """ # TODO(tyoshino): Terminate underlying TCP connection if possible. try: if mux.use_mux(request): mux.start(request, self) else: handler_suite = self.get_handler_suite(request.ws_resource) if handler_suite is None: raise DispatchException('No handler for: %r' % request.ws_resource) transfer_data_ = handler_suite.transfer_data transfer_data_(request) if not request.server_terminated: request.ws_stream.close_connection() # Catch non-critical exceptions the handler didn't handle. except handshake.AbortedByUserException as e: self._logger.debug('%s', util.get_stack_trace()) raise except msgutil.BadOperationException as e: self._logger.debug('%s', e) request.ws_stream.close_connection( common.STATUS_INTERNAL_ENDPOINT_ERROR) except msgutil.InvalidFrameException as e: # InvalidFrameException must be caught before # ConnectionTerminatedException that catches InvalidFrameException. self._logger.debug('%s', e) request.ws_stream.close_connection(common.STATUS_PROTOCOL_ERROR) except msgutil.UnsupportedFrameException as e: self._logger.debug('%s', e) request.ws_stream.close_connection(common.STATUS_UNSUPPORTED_DATA) except stream.InvalidUTF8Exception as e: self._logger.debug('%s', e) request.ws_stream.close_connection( common.STATUS_INVALID_FRAME_PAYLOAD_DATA) except msgutil.ConnectionTerminatedException as e: self._logger.debug('%s', e) except Exception as e: # Any other exceptions are forwarded to the caller of this # function. util.prepend_message_to_exception( '%s raised exception for %s: ' % ( _TRANSFER_DATA_HANDLER_NAME, request.ws_resource), e) raise
def _source(source_str): """Source a handler definition string.""" global_dic = {} try: exec source_str in global_dic except Exception: raise DispatchError('Error in sourcing handler:' + util.get_stack_trace()) return (_extract_handler(global_dic, _DO_EXTRA_HANDSHAKE_HANDLER_NAME), _extract_handler(global_dic, _TRANSFER_DATA_HANDLER_NAME))
def _source_handler_file(handler_definition): """Source a handler definition string. Args: handler_definition: a string containing Python statements that define handler functions. """ global_dic = {} try: exec handler_definition in global_dic except Exception: raise DispatchError('Error in sourcing handler:' + util.get_stack_trace()) return _HandlerSuite( _extract_handler(global_dic, _DO_EXTRA_HANDSHAKE_HANDLER_NAME), _extract_handler(global_dic, _TRANSFER_DATA_HANDLER_NAME))
def parse_request(self): """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request. Return True to continue processing for HTTP(S), False otherwise. """ result = CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self) if result: try: self._handshaker.do_handshake() try: self._dispatcher.transfer_data(self._request) except Exception, e: # Catch exception in transfer_data. # In this case, handshake has been successful, so just log # the exception and return False. logging.info('mod_pywebsocket: %s' % e) logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) return False except handshake.HandshakeError, e: # Handshake for ws(s) failed. Assume http(s). logging.info('mod_pywebsocket: %s' % e) return True
e.supported_versions) return apache.HTTP_BAD_REQUEST except handshake.HandshakeException, e: # Handshake for ws/wss failed. # Send http response with error status. request.log_error('mod_pywebsocket: %s' % e, apache.APLOG_INFO) return e.status handshake_is_done = True request._dispatcher = _dispatcher _dispatcher.transfer_data(request) except handshake.AbortedByUserException, e: request.log_error('mod_pywebsocket: %s' % e, apache.APLOG_INFO) except Exception, e: # DispatchException can also be thrown if something is wrong in # pywebsocket code. It's caught here, then. request.log_error( 'mod_pywebsocket: %s\n%s' % (e, util.get_stack_trace()), apache.APLOG_ERR) # Unknown exceptions before handshake mean Apache must handle its # request with another handler. if not handshake_is_done: return apache.DECLINED # Set assbackwards to suppress response header generation by Apache. request.assbackwards = 1 return apache.DONE # Return DONE such that no other handlers are invoked. # vi:sts=4 sw=4 et
except handshake.HandshakeException, e: # Handshake for ws/wss failed. # Send http response with error status. request.log_error( 'mod_pywebsocket: Handshake failed for error: %s' % e, apache.APLOG_INFO) return e.status handshake_is_done = True request._dispatcher = _dispatcher _dispatcher.transfer_data(request) except handshake.AbortedByUserException, e: request.log_error('mod_pywebsocket: Aborted: %s' % e, apache.APLOG_INFO) except Exception, e: # DispatchException can also be thrown if something is wrong in # pywebsocket code. It's caught here, then. request.log_error('mod_pywebsocket: Exception occurred: %s\n%s' % (e, util.get_stack_trace()), apache.APLOG_ERR) # Unknown exceptions before handshake mean Apache must handle its # request with another handler. if not handshake_is_done: return apache.DECLINED # Set assbackwards to suppress response header generation by Apache. request.assbackwards = 1 return apache.DONE # Return DONE such that no other handlers are invoked. # vi:sts=4 sw=4 et
def _main(args=None): """You can call this function from your own program, but please note that this function has some side-effects that might affect your program. For example, util.wrap_popen3_for_win use in this method replaces implementation of os.popen3. """ options, args = _parse_args_and_config(args=args) os.chdir(options.document_root) _configure_logging(options) if options.allow_draft75: logging.warning('--allow_draft75 option is obsolete.') if options.strict: logging.warning('--strict option is obsolete.') # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if options.tls_module is None: if _import_ssl(): options.tls_module = _TLS_BY_STANDARD_MODULE logging.debug('Using ssl module') elif _import_pyopenssl(): options.tls_module = _TLS_BY_PYOPENSSL logging.debug('Using pyOpenSSL module') else: logging.critical( 'TLS support requires ssl or pyOpenSSL module.') sys.exit(1) elif options.tls_module == _TLS_BY_STANDARD_MODULE: if not _import_ssl(): logging.critical('ssl module is not available') sys.exit(1) elif options.tls_module == _TLS_BY_PYOPENSSL: if not _import_pyopenssl(): logging.critical('pyOpenSSL module is not available') sys.exit(1) else: logging.critical('Invalid --tls-module option: %r', options.tls_module) sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if (options.tls_client_cert_optional and not options.tls_client_auth): logging.critical('Client authentication must be enabled to ' 'specify tls_client_cert_optional') sys.exit(1) else: if options.tls_module is not None: logging.critical('Use --tls-module option only together with ' '--use-tls option.') sys.exit(1) if options.tls_client_auth: logging.critical('TLS must be enabled for client authentication.') sys.exit(1) if options.tls_client_cert_optional: logging.critical('TLS must be enabled for client authentication.') sys.exit(1) if not options.scan_dir: options.scan_dir = options.websock_handlers if options.use_basic_auth: options.basic_auth_credential = 'Basic ' + base64.b64encode( options.basic_auth_credential) try: if options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(options.thread_monitor_interval_in_sec).start() server = WebSocketServer(options) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
def headerparserhandler(request): """Handle request. Args: request: mod_python request. This function is named headerparserhandler because it is the default name for a PythonHeaderParserHandler. """ handshake_is_done = False try: # Fallback to default http handler for request paths for which # we don't have request handlers. if not _dispatcher.get_handler_suite(request.uri): request.log_error( 'mod_pywebsocket: No handler for resource: %r' % request.uri, apache.APLOG_INFO) request.log_error( 'mod_pywebsocket: Fallback to Apache', apache.APLOG_INFO) return apache.DECLINED except dispatch.DispatchException as e: request.log_error( 'mod_pywebsocket: Dispatch failed for error: %s' % e, apache.APLOG_INFO) if not handshake_is_done: return e.status try: allow_draft75 = _parse_option( _PYOPT_ALLOW_DRAFT75, apache.main_server.get_options().get(_PYOPT_ALLOW_DRAFT75), _PYOPT_ALLOW_DRAFT75_DEFINITION) try: handshake.do_handshake( request, _dispatcher, allowDraft75=allow_draft75) except handshake.VersionException as e: request.log_error( 'mod_pywebsocket: Handshake failed for version error: %s' % e, apache.APLOG_INFO) request.err_headers_out.add(common.SEC_WEBSOCKET_VERSION_HEADER, e.supported_versions) return apache.HTTP_BAD_REQUEST except handshake.HandshakeException as e: # Handshake for ws/wss failed. # Send http response with error status. request.log_error( 'mod_pywebsocket: Handshake failed for error: %s' % e, apache.APLOG_INFO) return e.status handshake_is_done = True request._dispatcher = _dispatcher _dispatcher.transfer_data(request) except handshake.AbortedByUserException as e: request.log_error('mod_pywebsocket: Aborted: %s' % e, apache.APLOG_INFO) except Exception as e: # DispatchException can also be thrown if something is wrong in # pywebsocket code. It's caught here, then. request.log_error('mod_pywebsocket: Exception occurred: %s\n%s' % (e, util.get_stack_trace()), apache.APLOG_ERR) # Unknown exceptions before handshake mean Apache must handle its # request with another handler. if not handshake_is_done: return apache.DECLINED # Set assbackwards to suppress response header generation by Apache. request.assbackwards = 1 return apache.DONE # Return DONE such that no other handlers are invoked.
logger.warning('%s' % e) return False try: self._request._dispatcher = self._options.dispatcher self._options.dispatcher.transfer_data(self._request) except dispatch.DispatchException, e: logger.warning('%s' % e) return False except handshake.AbortedByUserException, e: logger.warning('%s' % e) except Exception, e: # Catch exception in transfer_data. # In this case, handshake has been successful, so just log # the exception and return False. logger.warning('%s' % e) logger.warning('%s' % util.get_stack_trace()) except dispatch.DispatchException, e: logger.warning('%s' % e) self.send_error(e.status) except handshake.HandshakeException, e: # Handshake for ws(s) failed. Assume http(s). logger.info('%s' % e) self.send_error(e.status) except Exception, e: logger.warning('%s' % e) logger.warning('%s' % util.get_stack_trace()) return False def log_request(self, code='-', size='-'): """Override BaseHTTPServer.log_request."""
def _main(args=None): options, args = _parse_args_and_config(args=args) os.chdir(options.document_root) _configure_logging(options) # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if not (_HAS_SSL or _HAS_OPEN_SSL): logging.critical('TLS support requires ssl or pyOpenSSL module.') sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if options.tls_client_auth: if not options.use_tls: logging.critical('TLS must be enabled for client authentication.') sys.exit(1) if not _HAS_SSL: logging.critical('Client authentication requires ssl module.') if not options.scan_dir: options.scan_dir = options.websock_handlers if options.use_basic_auth: options.basic_auth_credential = 'Basic ' + base64.b64encode( options.basic_auth_credential) try: if options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(options.thread_monitor_interval_in_sec).start() server = WebSocketServer(options) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
# In this case, handshake has been successful, so just log # the exception and return False. logging.info('mod_pywebsocket: %s' % e) logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) return False except handshake.HandshakeError, e: # Handshake for ws(s) failed. Assume http(s). logging.info('mod_pywebsocket: %s' % e) return True except dispatch.DispatchError, e: logging.warning('mod_pywebsocket: %s' % e) return False except Exception, e: logging.warning('mod_pywebsocket: %s' % e) logging.warning('mod_pywebsocket: %s' % util.get_stack_trace()) return False return result def log_request(self, code='-', size='-'): """Override BaseHTTPServer.log_request.""" logging.info('"%s" %s %s', self.requestline, str(code), str(size)) def log_error(self, *args): """Override BaseHTTPServer.log_error.""" # Despite the name, this method is for warnings than for errors. # For example, HTTP status code is logged by this method. logging.warn('%s - %s' % (self.address_string(), (args[0] % args[1:])))
except Exception, e: # Catch exception in transfer_data. # In this case, handshake has been successful, so just log # the exception and return False. logging.info('mod_pywebsocket: %s' % e) return False except handshake.HandshakeError, e: # Handshake for ws(s) failed. Assume http(s). logging.info('mod_pywebsocket: %s' % e) return True except dispatch.DispatchError, e: logging.warning('mod_pywebsocket: %s' % e) return False except Exception, e: logging.warning('mod_pywebsocket: %s' % e) logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) return False return result def log_request(self, code='-', size='-'): """Override BaseHTTPServer.log_request.""" logging.info('"%s" %s %s', self.requestline, str(code), str(size)) def log_error(self, *args): """Override BaseHTTPServer.log_error.""" # Despite the name, this method is for warnings than for errors. # For example, HTTP status code is logged by this method. logging.warn('%s - %s' % (self.address_string(), (args[0] % args[1:])))
def _main(args=None): """You can call this function from your own program, but please note that this function has some side-effects that might affect your program. For example, util.wrap_popen3_for_win use in this method replaces implementation of os.popen3. """ options, args = _parse_args_and_config(args=args) os.chdir(options.document_root) _configure_logging(options) # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if not (_HAS_SSL or _HAS_OPEN_SSL): logging.critical('TLS support requires ssl or pyOpenSSL module.') sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if options.tls_client_auth: if not options.use_tls: logging.critical('TLS must be enabled for client authentication.') sys.exit(1) if not _HAS_SSL: logging.critical('Client authentication requires ssl module.') if not options.scan_dir: options.scan_dir = options.websock_handlers if options.use_basic_auth: options.basic_auth_credential = 'Basic ' + base64.b64encode( options.basic_auth_credential) try: if options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(options.thread_monitor_interval_in_sec).start() server = WebSocketServer(options) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
def _main(args=None): options, args = _parse_args_and_config(args=args) os.chdir(options.document_root) _configure_logging(options) # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if not (_HAS_SSL or _HAS_OPEN_SSL): logging.critical('TLS support requires ssl or pyOpenSSL module.') sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if options.tls_client_auth: if not options.use_tls: logging.critical('TLS must be enabled for client authentication.') sys.exit(1) if not _HAS_SSL: logging.critical('Client authentication requires ssl module.') if not options.scan_dir: options.scan_dir = options.websock_handlers if options.use_basic_auth: options.basic_auth_credential = 'Basic ' + base64.b64encode( options.basic_auth_credential) try: if options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(options.thread_monitor_interval_in_sec).start() # Share a Dispatcher among request handlers to save time for # instantiation. Dispatcher can be shared because it is thread-safe. options.dispatcher = dispatch.Dispatcher( options.websock_handlers, options.scan_dir, options.allow_handlers_outside_root_dir) if options.websock_handlers_map_file: _alias_handlers(options.dispatcher, options.websock_handlers_map_file) warnings = options.dispatcher.source_warnings() if warnings: for warning in warnings: logging.warning('mod_pywebsocket: %s' % warning) server = WebSocketServer(options) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
def handle_error(self, request, client_address): self._logger.error('WS exception in processing request from: %r\n%s', client_address, util.get_stack_trace())
def run(user_data = []): parser = optparse.OptionParser() parser.add_option('-H', '--server-host', '--server_host', dest='server_host', default='', help='server hostname to listen to') parser.add_option('-V', '--validation-host', '--validation_host', dest='validation_host', default=None, help='server hostname to validate in absolute path.') parser.add_option('-p', '--port', dest='port', type='int', default=common.DEFAULT_WEB_SOCKET_PORT, help='port to listen to') parser.add_option('-P', '--validation-port', '--validation_port', dest='validation_port', type='int', default=None, help='server port to validate in absolute path.') parser.add_option('-w', '--websock-handlers', '--websock_handlers', dest='websock_handlers', default='.', help='WebSocket handlers root directory.') parser.add_option('-m', '--websock-handlers-map-file', '--websock_handlers_map_file', dest='websock_handlers_map_file', default=None, help=('WebSocket handlers map file. ' 'Each line consists of alias_resource_path and ' 'existing_resource_path, separated by spaces.')) parser.add_option('-s', '--scan-dir', '--scan_dir', dest='scan_dir', default=None, help=('WebSocket handlers scan directory. ' 'Must be a directory under websock_handlers.')) parser.add_option('-d', '--document-root', '--document_root', dest='document_root', default='.', help='Document root directory.') parser.add_option('-x', '--cgi-paths', '--cgi_paths', dest='cgi_paths', default=None, help=('CGI paths relative to document_root.' 'Comma-separated. (e.g -x /cgi,/htbin) ' 'Files under document_root/cgi_path are handled ' 'as CGI programs. Must be executable.')) parser.add_option('-t', '--tls', dest='use_tls', action='store_true', default=False, help='use TLS (wss://)') parser.add_option('-k', '--private-key', '--private_key', dest='private_key', default='', help='TLS private key file.') parser.add_option('-c', '--certificate', dest='certificate', default='', help='TLS certificate file.') parser.add_option('-l', '--log-file', '--log_file', dest='log_file', default='', help='Log file.') parser.add_option('--log-level', '--log_level', type='choice', dest='log_level', default='warn', choices=['debug', 'info', 'warning', 'warn', 'error', 'critical'], help='Log level.') parser.add_option('--log-max', '--log_max', dest='log_max', type='int', default=_DEFAULT_LOG_MAX_BYTES, help='Log maximum bytes') parser.add_option('--log-count', '--log_count', dest='log_count', type='int', default=_DEFAULT_LOG_BACKUP_COUNT, help='Log backup count') parser.add_option('--allow-draft75', dest='allow_draft75', action='store_true', default=False, help='Allow draft 75 handshake') parser.add_option('--strict', dest='strict', action='store_true', default=False, help='Strictly check handshake request') parser.add_option('-q', '--queue', dest='request_queue_size', type='int', default=_DEFAULT_REQUEST_QUEUE_SIZE, help='request queue size') options = parser.parse_args()[0] os.chdir(options.document_root) standalone._configure_logging(options) # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if not _HAS_OPEN_SSL: logging.critical('To use TLS, install pyOpenSSL.') sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if not options.scan_dir: options.scan_dir = options.websock_handlers try: # Share a Dispatcher among request handlers to save time for # instantiation. Dispatcher can be shared because it is thread-safe. dump_reveived_data = True options.dispatcher = FunctionDispatcher(my_receive_function, user_data) standalone._print_warnings_if_any(options.dispatcher) server = WebSocketServer(options) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
def handle_error(self, rquest, client_address): """Override SocketServer.handle_error.""" logging.error( ('Exception in processing request from: %r' % (client_address,)) + '\n' + util.get_stack_trace())
def _main(): parser = optparse.OptionParser() parser.add_option('-H', '--server-host', '--server_host', dest='server_host', default='', help='server hostname to listen to') parser.add_option('-p', '--port', dest='port', type='int', default=common.DEFAULT_WEB_SOCKET_PORT, help='port to listen to') parser.add_option('-w', '--websock-handlers', '--websock_handlers', dest='websock_handlers', default='.', help='WebSocket handlers root directory.') parser.add_option('-m', '--websock-handlers-map-file', '--websock_handlers_map_file', dest='websock_handlers_map_file', default=None, help=('WebSocket handlers map file. ' 'Each line consists of alias_resource_path and ' 'existing_resource_path, separated by spaces.')) parser.add_option('-s', '--scan-dir', '--scan_dir', dest='scan_dir', default=None, help=('WebSocket handlers scan directory. ' 'Must be a directory under websock_handlers.')) parser.add_option('-d', '--document-root', '--document_root', dest='document_root', default='.', help='Document root directory.') parser.add_option('-x', '--cgi-paths', '--cgi_paths', dest='cgi_paths', default=None, help=('CGI paths relative to document_root.' 'Comma-separated. (e.g -x /cgi,/htbin) ' 'Files under document_root/cgi_path are handled ' 'as CGI programs. Must be executable.')) parser.add_option('-t', '--tls', dest='use_tls', action='store_true', default=False, help='use TLS (wss://)') parser.add_option('-k', '--private-key', '--private_key', dest='private_key', default='', help='TLS private key file.') parser.add_option('-c', '--certificate', dest='certificate', default='', help='TLS certificate file.') parser.add_option('-l', '--log-file', '--log_file', dest='log_file', default='', help='Log file.') parser.add_option( '--log-level', '--log_level', type='choice', dest='log_level', default='warn', choices=['debug', 'info', 'warning', 'warn', 'error', 'critical'], help='Log level.') parser.add_option('--log-max', '--log_max', dest='log_max', type='int', default=_DEFAULT_LOG_MAX_BYTES, help='Log maximum bytes') parser.add_option('--log-count', '--log_count', dest='log_count', type='int', default=_DEFAULT_LOG_BACKUP_COUNT, help='Log backup count') parser.add_option('--allow-draft75', dest='allow_draft75', action='store_true', default=False, help='Allow draft 75 handshake') parser.add_option('--strict', dest='strict', action='store_true', default=False, help='Strictly check handshake request') parser.add_option('-q', '--queue', dest='request_queue_size', type='int', default=_DEFAULT_REQUEST_QUEUE_SIZE, help='request queue size') options = parser.parse_args()[0] os.chdir(options.document_root) _configure_logging(options) SocketServer.TCPServer.request_queue_size = options.request_queue_size CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = [] if options.cgi_paths: CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = \ options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) CGIHTTPServer.executable = __check_script if options.use_tls: if not _HAS_OPEN_SSL: logging.critical('To use TLS, install pyOpenSSL.') sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if not options.scan_dir: options.scan_dir = options.websock_handlers try: # Share a Dispatcher among request handlers to save time for # instantiation. Dispatcher can be shared because it is thread-safe. options.dispatcher = dispatch.Dispatcher(options.websock_handlers, options.scan_dir) if options.websock_handlers_map_file: _alias_handlers(options.dispatcher, options.websock_handlers_map_file) _print_warnings_if_any(options.dispatcher) WebSocketRequestHandler.options = options WebSocketServer.options = options server = WebSocketServer((options.server_host, options.port), WebSocketRequestHandler) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
def handle_error(self, request, client_address): """Override SocketServer.handle_error.""" logger.error('Failed to process request from: %r\n%s', \ client_address, util.get_stack_trace())
# Catch exception in transfer_data. # In this case, handshake has been successful, so just log # the exception and return False. logging.info('mod_pywebsocket: %s' % e) logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) return False except handshake.HandshakeError, e: # Handshake for ws(s) failed. Assume http(s). logging.info('mod_pywebsocket: %s' % e) return True except dispatch.DispatchError, e: logging.warning('mod_pywebsocket: %s' % e) return False except Exception, e: logging.warning('mod_pywebsocket: %s' % e) logging.warning('mod_pywebsocket: %s' % util.get_stack_trace()) return False return result def log_request(self, code='-', size='-'): """Override BaseHTTPServer.log_request.""" logging.info('"%s" %s %s', self.requestline, str(code), str(size)) def log_error(self, *args): """Override BaseHTTPServer.log_error.""" # Despite the name, this method is for warnings than for errors. # For example, HTTP status code is logged by this method. logging.warn('%s - %s' % (self.address_string(), (args[0] % args[1:])))
# Handshake for ws/wss failed. # Send http response with error status. request.log_error( 'mod_pywebsocket: Handshake failed for error: %s' % e, apache.APLOG_INFO) return e.status handshake_is_done = True request._dispatcher = _dispatcher _dispatcher.transfer_data(request) except handshake.AbortedByUserException, e: request.log_error('mod_pywebsocket: Aborted: %s' % e, apache.APLOG_INFO) except Exception, e: # DispatchException can also be thrown if something is wrong in # pywebsocket code. It's caught here, then. request.log_error( 'mod_pywebsocket: Exception occurred: %s\n%s' % (e, util.get_stack_trace()), apache.APLOG_ERR) # Unknown exceptions before handshake mean Apache must handle its # request with another handler. if not handshake_is_done: return apache.DECLINED # Set assbackwards to suppress response header generation by Apache. request.assbackwards = 1 return apache.DONE # Return DONE such that no other handlers are invoked. # vi:sts=4 sw=4 et
logger.warning("%s" % e) return False try: self._request._dispatcher = self._options.dispatcher self._options.dispatcher.transfer_data(self._request) except dispatch.DispatchException, e: logger.warning("%s" % e) return False except handshake.AbortedByUserException, e: logger.warning("%s" % e) except Exception, e: # Catch exception in transfer_data. # In this case, handshake has been successful, so just log # the exception and return False. logger.warning("%s" % e) logger.warning("%s" % util.get_stack_trace()) except dispatch.DispatchException, e: logger.warning("%s" % e) self.send_error(e.status) except handshake.HandshakeException, e: # Handshake for ws(s) failed. Assume http(s). logger.info("%s" % e) self.send_error(e.status) except Exception, e: logger.warning("%s" % e) logger.warning("%s" % util.get_stack_trace()) return False def log_request(self, code="-", size="-"): """Override BaseHTTPServer.log_request."""
def _main(args=None): parser = _build_option_parser() options, args = parser.parse_args(args=args) if args: logging.critical('Unrecognized positional arguments: %r', args) sys.exit(1) os.chdir(options.document_root) _configure_logging(options) # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.wrap_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if not _HAS_OPEN_SSL: logging.critical('To use TLS, install pyOpenSSL.') sys.exit(1) if not options.private_key or not options.certificate: logging.critical( 'To use TLS, specify private_key and certificate.') sys.exit(1) if not options.scan_dir: options.scan_dir = options.websock_handlers try: if options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(options.thread_monitor_interval_in_sec).start() # Share a Dispatcher among request handlers to save time for # instantiation. Dispatcher can be shared because it is thread-safe. options.dispatcher = dispatch.Dispatcher( options.websock_handlers, options.scan_dir, options.allow_handlers_outside_root_dir) if options.websock_handlers_map_file: _alias_handlers(options.dispatcher, options.websock_handlers_map_file) warnings = options.dispatcher.source_warnings() if warnings: for warning in warnings: logging.warning('mod_pywebsocket: %s' % warning) server = WebSocketServer(options) server.serve_forever() except Exception, e: logging.critical('mod_pywebsocket: %s' % e) logging.critical('mod_pywebsocket: %s' % util.get_stack_trace()) sys.exit(1)
def _main(args=None): """ You can call this function from your own program, but please note that this function has some side-effects that might affect your program. For example, util.layer_popen3_for_win use in this method replaces implementation of os.popen3 """ options, args = _parse_args_and_config(args=args) os.chdir(options.document_root) _configure_logging(options) if options.allow_draft75: logging.warning(_('--allow_draft75 option is obsolete')) if options.strict: logging.warning(_('--strict option is obsolete')) # TODO(tyoshino): Clean up initialization of CGI related values. Move some # of code here to WebSocketRequestHandler class if it's better. options.cgi_directories = [] options.is_executable_method = None if options.cgi_paths: options.cgi_directories = options.cgi_paths.split(',') if sys.platform in ('cygwin', 'win32'): cygwin_path = None # For Win32 Python, it is expected that CYGWIN_PATH # is set to a directory of cygwin binaries. # For example, websocket_server.py in Chromium sets CYGWIN_PATH to # full path of third_party/cygwin/bin. if 'CYGWIN_PATH' in os.environ: cygwin_path = os.environ['CYGWIN_PATH'] util.layer_popen3_for_win(cygwin_path) def __check_script(scriptpath): return util.get_script_interp(scriptpath, cygwin_path) options.is_executable_method = __check_script if options.use_tls: if options.tls_module is None: if _import_ssl(): options.tls_module = _TLS_BY_STANDARD_MODULE logging.debug('Using ssl module') elif _import_pyopenssl(): options.tls_module = _TLS_BY_PYOPENSSL logging.debug('Using pyOpenSSL module') else: logging.critical( _('TLS support requires ssl or pyOpenSSL module')) sys.exit(1) elif options.tls_module == _TLS_BY_STANDARD_MODULE: if not _import_ssl(): logging.critical(_('ssl module is not available')) sys.exit(1) elif options.tls_module == _TLS_BY_PYOPENSSL: if not _import_pyopenssl(): logging.critical(_('pyOpenSSL module is not available')) sys.exit(1) else: logging.critical( _("Invalid --tls-module option: {0}").format( options.tls_module)) sys.exit(1) if not options.private_key or not options.certificate: logging.critical( _('To use TLS, specify private_key and certificate')) sys.exit(1) if (options.tls_client_cert_optional and not options.tls_client_auth): logging.critical( _('Client authentication must be enabled to specify tls_client_cert_optional' )) sys.exit(1) else: if options.tls_module is not None: logging.critical( _('Use --tls-module option only together with --use-tls option' )) sys.exit(1) if options.tls_client_auth: logging.critical( _('TLS must be enabled for client authentication')) sys.exit(1) if options.tls_client_cert_optional: logging.critical( _('TLS must be enabled for client authentication')) sys.exit(1) if not options.scan_dir: options.scan_dir = options.websock_handlers if options.use_basic_auth: options.basic_auth_credential = "Basic {0}".format( base64.b64encode(options.basic_auth_credential)) try: if options.thread_monitor_interval_in_sec > 0: # Run a thread monitor to show the status of server threads for # debugging. ThreadMonitor(options.thread_monitor_interval_in_sec).start() server = WebSocketServer(options) server.serve_forever() except Exception as e: logging.critical(_("mod_pywebsocket: {0}").format(e.message)) logging.critical( _("mod_pywebsocket: {0}").format(util.get_stack_trace())) sys.exit(1)