Example #1
0
 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)
Example #2
0
 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)
Example #3
0
    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
Example #4
0
    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)
Example #5
0
    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
Example #6
0
    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())
Example #7
0
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)
Example #8
0
    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
Example #9
0
    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
Example #10
0
    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())
Example #11
0
    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())
Example #12
0
    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())
Example #13
0
 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()))
Example #14
0
    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
Example #15
0
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)
Example #16
0
    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
Example #17
0
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))
Example #18
0
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))
Example #19
0
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))
Example #20
0
    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
Example #21
0
    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
Example #23
0
        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
Example #24
0
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.
Example #26
0
                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."""
Example #27
0
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)
Example #28
0
                    # 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:])))
Example #29
0
                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:])))
Example #30
0
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)
Example #31
0
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)
Example #32
0
 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())
Example #33
0
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)    
Example #34
0
    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())
Example #35
0
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)
Example #36
0
 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())
Example #37
0
                    # 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:])))
Example #38
0
            # 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
Example #39
0
                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."""
Example #40
0
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)
Example #41
0
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)
Example #42
0
        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