def handle_ws(self, resource):
        request = standalone._StandaloneRequest(self, self.server.using_tls)
        try:
            try:
                handshake.do_handshake(
                    request,
                    self.server.wsdispatcher,
                    allowDraft75=self.server.draft75,
                    strict=self.server.strict_draft75)
            except handshake.VersionException:
                e = sys.exc_info()[1]
                self._logger.info('WS handshake version error: %s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException:
                # Handshake for ws(s) failed.
                e = sys.exc_info()[1]
                self._logger.info('WS handshake error: %s', e)
                self.send_error(e.status)
                return False

            request._dispatcher = self.server.wsdispatcher
            self.server.wsdispatcher.receive_data(request, resource)
        except handshake.AbortedByUserException:
            e = sys.exc_info()[1]
            self._logger.info('WS handshake aborted: %s', e)
        return False
Example #2
0
    def parse_request(self):
        """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request.

        Return True to continue processing for HTTP(S), False otherwise.

        See BaseHTTPRequestHandler.handle_one_request method which calls
        this method to understand how the return value will be handled.
        """

        # We hook parse_request method, but also call the original
        # CGIHTTPRequestHandler.parse_request since when we return False,
        # CGIHTTPRequestHandler.handle_one_request continues processing and
        # it needs variables set by CGIHTTPRequestHandler.parse_request.
        #
        # Variables set by this method will be also used by WebSocket request
        # handling. See _StandaloneRequest.get_request, etc.
        cgi_req = CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self)
        if not cgi_req:
            return False
        host, port, resource = http_header_util.parse_uri(self.path)
        if resource is None:
            logger.warning('invalid uri %r' % self.path)
            return True
        server_options = self.server.websocket_server_options
        if host is not None:
            validation_host = server_options.validation_host
            if validation_host is not None and host != validation_host:
                logger.warning('invalid host %r '
                             '(expected: %r)' % (host, validation_host))
                return True
        if port is not None:
            validation_port = server_options.validation_port
            if validation_port is not None and port != validation_port:
                logger.warning('invalid port %r '
                             '(expected: %r)' % (port, validation_port))
                return True
        self.path = resource

        try:
            # Fallback to default http handler for request paths for which
            # we don't have request handlers.
            if not self._options.dispatcher.get_handler_suite(self.path):
                self.path = "/"
                 # we fall back to our default method if nothing higher is around...
            try:
                handshake.do_handshake(
                    self._request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.AbortedByUserException, e:
                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
Example #3
0
    def parse_request(self):
        """
        Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request.

        Return True to continue processing for HTTP(S), False otherwise.

        See BaseHTTPRequestHandler.handle_one_request method which calls
        this method to understand how the return value will be handled
        """

        # We hook parse_request method, but also call the original
        # CGIHTTPRequestHandler.parse_request since when we return False,
        # CGIHTTPRequestHandler.handle_one_request continues processing and
        # it needs variables set by CGIHTTPRequestHandler.parse_request.
        #
        # Variables set by this method will be also used by WebSocket request
        # handling (self.path, self.command, self.requestline, etc. See also
        # how _StandaloneRequest's members are implemented using these
        # attributes).

        # Modified
        # Most True values converted into False
        if not http.server.CGIHTTPRequestHandler.parse_request(self):
            return False

        if self._options.use_basic_auth:
            auth = self.headers.getheader('Authorization')
            if auth != self._options.basic_auth_credential:
                self.send_response(401)
                self.send_header('WWW-Authenticate',
                                 'Basic realm="Pywebsocket"')
                self.end_headers()
                self._logger.info(_('Request basic authentication'))
                return True

        host, port, resource = http_header_util.parse_uri(self.path)
        if resource is None:
            self._logger.info(_("Invalid URI: {0}").format(self.path))
            self._logger.info(_('Fallback to CGIHTTPRequestHandler'))
            return False
        server_options = self.server.websocket_server_options
        if host is not None:
            validation_host = server_options.validation_host
            if validation_host is not None and host != validation_host:
                self._logger.info(
                    _('Invalid host: {0:d} (expected: {1})').format(
                        host, validation_host))
                self._logger.info(_('Fallback to CGIHTTPRequestHandler'))
                return False
        if port is not None:
            validation_port = server_options.validation_port
            if validation_port is not None and port != validation_port:
                self._logger.info(
                    _('Invalid port: {0:d} (expected: {1})').format(
                        port, validation_port))
                self._logger.info(_('Fallback to CGIHTTPRequestHandler'))
                return False
        self.path = resource

        request = _StandaloneRequest(self, self._options.use_tls)

        try:
            # Fallback to default http handler for request paths for which
            # we do not have request handlers.
            if not self._options.dispatcher.get_handler_suite(self.path):
                self._logger.info(
                    _("No handler for resource: {0}").format(self.path))
                self._logger.info(_('Fallback to CGIHTTPRequestHandler'))
                return False
        except dispatch.DispatchException as e:
            self._logger.info(
                _("Dispatch failed for error: {0}").format(e.message))
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException as e:
                self._logger.info(
                    _("Handshake failed for version error: {0}").format(
                        e.message))
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException as e:
                # Handshake for ws(s) failed.
                self._logger.info(
                    _("Handshake failed for error: {0}").format(e.message))
                self.send_error(e.status)
                return False

            request._dispatcher = self._options.dispatcher
            self._options.dispatcher.transfer_data(request)
        except handshake.AbortedByUserException as e:
            self._logger.info(_("Aborted: {0}").format(e.message))
        return False
Example #4
0
class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
    """CGIHTTPRequestHandler specialized for WebSocket."""

    # Use httplib.HTTPMessage instead of mimetools.Message.
    MessageClass = httplib.HTTPMessage

    def setup(self):
        """Override SocketServer.StreamRequestHandler.setup to wrap rfile
        with MemorizingFile.

        This method will be called by BaseRequestHandler's constructor
        before calling BaseHTTPRequestHandler.handle.
        BaseHTTPRequestHandler.handle will call
        BaseHTTPRequestHandler.handle_one_request and it will call
        WebSocketRequestHandler.parse_request.
        """

        # Call superclass's setup to prepare rfile, wfile, etc. See setup
        # definition on the root class SocketServer.StreamRequestHandler to
        # understand what this does.
        CGIHTTPServer.CGIHTTPRequestHandler.setup(self)

        self.rfile = memorizingfile.MemorizingFile(
            self.rfile, max_memorized_lines=_MAX_MEMORIZED_LINES)

    def __init__(self, request, client_address, server):
        self._logger = util.get_class_logger(self)

        self._options = server.websocket_server_options

        # Overrides CGIHTTPServerRequestHandler.cgi_directories.
        self.cgi_directories = self._options.cgi_directories
        # Replace CGIHTTPRequestHandler.is_executable method.
        if self._options.is_executable_method is not None:
            self.is_executable = self._options.is_executable_method

        # This actually calls BaseRequestHandler.__init__.
        CGIHTTPServer.CGIHTTPRequestHandler.__init__(self, request,
                                                     client_address, server)

    def parse_request(self):
        """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request.

        Return True to continue processing for HTTP(S), False otherwise.

        See BaseHTTPRequestHandler.handle_one_request method which calls
        this method to understand how the return value will be handled.
        """

        # We hook parse_request method, but also call the original
        # CGIHTTPRequestHandler.parse_request since when we return False,
        # CGIHTTPRequestHandler.handle_one_request continues processing and
        # it needs variables set by CGIHTTPRequestHandler.parse_request.
        #
        # Variables set by this method will be also used by WebSocket request
        # handling (self.path, self.command, self.requestline, etc. See also
        # how _StandaloneRequest's members are implemented using these
        # attributes).
        if not CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self):
            return False

        if self._options.use_basic_auth:
            auth = self.headers.getheader('Authorization')
            if auth != self._options.basic_auth_credential:
                self.send_response(401)
                self.send_header('WWW-Authenticate',
                                 'Basic realm="Pywebsocket"')
                self.end_headers()
                self._logger.info('Request basic authentication')
                return True

        host, port, resource = http_header_util.parse_uri(self.path)
        if resource is None:
            self._logger.info('Invalid URI: %r', self.path)
            self._logger.info('Fallback to CGIHTTPRequestHandler')
            return True
        server_options = self.server.websocket_server_options
        if host is not None:
            validation_host = server_options.validation_host
            if validation_host is not None and host != validation_host:
                self._logger.info('Invalid host: %r (expected: %r)', host,
                                  validation_host)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        if port is not None:
            validation_port = server_options.validation_port
            if validation_port is not None and port != validation_port:
                self._logger.info('Invalid port: %r (expected: %r)', port,
                                  validation_port)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        self.path = resource

        request = _StandaloneRequest(self, self._options.use_tls)

        try:
            # Fallback to default http handler for request paths for which
            # we don't have request handlers.
            if not self._options.dispatcher.get_handler_suite(self.path):
                self._logger.info('No handler for resource: %r', self.path)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        except dispatch.DispatchException, e:
            self._logger.info('%s', e)
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException, e:
                self._logger.info('%s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException, e:
                # Handshake for ws(s) failed.
                self._logger.info('%s', e)
                self.send_error(e.status)
                return False
Example #5
0
class ChopWebSocketRequestHandler(standalone.WebSocketRequestHandler):
    def parse_request(self):
        """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request.

        Return True to continue processing for HTTP(S), False otherwise.

        See BaseHTTPRequestHandler.handle_one_request method which calls
        this method to understand how the return value will be handled.
        """

        # We hook parse_request method, but also call the original
        # CGIHTTPRequestHandler.parse_request since when we return False,
        # CGIHTTPRequestHandler.handle_one_request continues processing and
        # it needs variables set by CGIHTTPRequestHandler.parse_request.
        #
        # Variables set by this method will be also used by WebSocket request
        # handling (self.path, self.command, self.requestline, etc. See also
        # how _StandaloneRequest's members are implemented using these
        # attributes).
        if not CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self):
            return False

        host, port, resource = http_header_util.parse_uri(self.path)
        if resource is None:
            self._logger.info('Invalid URI: %r', self.path)
            self._logger.info('Fallback to CGIHTTPRequestHandler')
            return True
        server_options = self.server.websocket_server_options
        if host is not None:
            validation_host = server_options.validation_host
            if validation_host is not None and host != validation_host:
                self._logger.info('Invalid host: %r (expected: %r)', host,
                                  validation_host)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        if port is not None:
            validation_port = server_options.validation_port
            if validation_port is not None and port != validation_port:
                self._logger.info('Invalid port: %r (expected: %r)', port,
                                  validation_port)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        self.path = resource

        request = standalone._StandaloneRequest(self, self._options.use_tls)

        try:
            # Fallback to default http handler for request paths for which
            # we don't have request handlers.
            #TODO fill in path determination for static files and this
            #if not self._options.dispatcher.get_handler_suite(self.path):
            self._logger.debug("Path : %r", self.path)
            if self.path != "/data" and self.path != "/shell":
                return True
        except dispatch.DispatchException, e:
            self._logger.info('%s', e)
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.
                    dispatcher,  #This should now be custom dispatcher
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException, e:
                self._logger.info('%s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException, e:
                # Handshake for ws(s) failed.
                self._logger.info('%s', e)
                self.send_error(e.status)
                return False
Example #6
0
            return apache.DECLINED
    except dispatch.DispatchException, 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, 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, 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
Example #7
0
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return False
        except dispatch.DispatchException, e:
            self._logger.info('%s', e)
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException, e:
                self._logger.info('%s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException, e:
                # Handshake for ws(s) failed.
                self._logger.info('%s', e)
                self.send_error(e.status)
                return False
Example #8
0
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return False
        except dispatch.DispatchException, e:
            self._logger.info('Dispatch failed for error: %s', e)
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException, e:
                self._logger.info('Handshake failed for version error: %s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException, e:
                # Handshake for ws(s) failed.
                self._logger.info('Handshake failed for error: %s', e)
                self.send_error(e.status)
                return False
Example #9
0
    def parse_request(self):
        """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request.

        Return True to continue processing for HTTP(S), False otherwise.

        See BaseHTTPRequestHandler.handle_one_request method which calls
        this method to understand how the return value will be handled.
        """

        # We hook parse_request method, but also call the original
        # CGIHTTPRequestHandler.parse_request since when we return False,
        # CGIHTTPRequestHandler.handle_one_request continues processing and
        # it needs variables set by CGIHTTPRequestHandler.parse_request.
        #
        # Variables set by this method will be also used by WebSocket request
        # handling (self.path, self.command, self.requestline, etc. See also
        # how _StandaloneRequest's members are implemented using these
        # attributes).
        if not CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self):
            return False

        if self.command == "CONNECT":
            self.send_response(200, "Connected")
            self.send_header("Connection", "keep-alive")
            self.end_headers()
            return False

        if self._options.use_basic_auth:
            auth = self.headers.getheader('Authorization')
            if auth != self._options.basic_auth_credential:
                self.send_response(401)
                self.send_header('WWW-Authenticate',
                                 'Basic realm="Pywebsocket"')
                self.end_headers()
                self._logger.info('Request basic authentication')
                return False

        # Special paths for XMLHttpRequest benchmark
        xhr_benchmark_helper_prefix = '/073be001e10950692ccbf3a2ad21c245'
        parsed_path = urllib.parse.urlsplit(self.path)
        if parsed_path.path == (xhr_benchmark_helper_prefix + '_send'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_send()
            return False
        if parsed_path.path == (xhr_benchmark_helper_prefix + '_receive'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_receive_and_parse()
            return False
        if parsed_path.path == (xhr_benchmark_helper_prefix +
                                '_receive_getnocache'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_receive(
                int(parsed_path.query), False, False)
            return False
        if parsed_path.path == (xhr_benchmark_helper_prefix +
                                '_receive_getcache'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_receive(
                int(parsed_path.query), False, True)
            return False

        host, port, resource = http_header_util.parse_uri(self.path)
        if resource is None:
            self._logger.info('Invalid URI: %r', self.path)
            self._logger.info('Fallback to CGIHTTPRequestHandler')
            return True
        server_options = self.server.websocket_server_options
        if host is not None:
            validation_host = server_options.validation_host
            if validation_host is not None and host != validation_host:
                self._logger.info('Invalid host: %r (expected: %r)',
                                  host,
                                  validation_host)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        if port is not None:
            validation_port = server_options.validation_port
            if validation_port is not None and port != validation_port:
                self._logger.info('Invalid port: %r (expected: %r)',
                                  port,
                                  validation_port)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        self.path = resource

        request = _StandaloneRequest(self, self._options.use_tls)

        try:
            # Fallback to default http handler for request paths for which
            # we don't have request handlers.
            if not self._options.dispatcher.get_handler_suite(self.path):
                self._logger.info('No handler for resource: %r',
                                  self.path)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        except dispatch.DispatchException as e:
            self._logger.info('Dispatch failed for error: %s', e)
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException as e:
                self._logger.info('Handshake failed for version error: %s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException as e:
                # Handshake for ws(s) failed.
                self._logger.info('Handshake failed for error: %s', e)
                self.send_error(e.status)
                return False

            request._dispatcher = self._options.dispatcher
            self._options.dispatcher.transfer_data(request)
        except handshake.AbortedByUserException as e:
            self._logger.info('Aborted: %s', e)
        return False
Example #10
0
            return apache.DECLINED
    except dispatch.DispatchException, 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, 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, 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
Example #11
0
    def parse_request(self):
        """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request.

        Return True to continue processing for HTTP(S), False otherwise.

        See BaseHTTPRequestHandler.handle_one_request method which calls
        this method to understand how the return value will be handled.
        """

        # We hook parse_request method, but also call the original
        # CGIHTTPRequestHandler.parse_request since when we return False,
        # CGIHTTPRequestHandler.handle_one_request continues processing and
        # it needs variables set by CGIHTTPRequestHandler.parse_request.
        #
        # Variables set by this method will be also used by WebSocket request
        # handling (self.path, self.command, self.requestline, etc. See also
        # how _StandaloneRequest's members are implemented using these
        # attributes).
        if not CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self):
            return False

        if self.command == "CONNECT":
            self.send_response(200, "Connected")
            self.send_header("Connection", "keep-alive")
            self.end_headers()
            return False

        if self._options.use_basic_auth:
            auth = self.headers.getheader('Authorization')
            if auth != self._options.basic_auth_credential:
                self.send_response(401)
                self.send_header('WWW-Authenticate',
                                 'Basic realm="Pywebsocket"')
                self.end_headers()
                self._logger.info('Request basic authentication')
                return False

        # Special paths for XMLHttpRequest benchmark
        xhr_benchmark_helper_prefix = '/073be001e10950692ccbf3a2ad21c245'
        parsed_path = urllib.parse.urlsplit(self.path)
        if parsed_path.path == (xhr_benchmark_helper_prefix + '_send'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_send()
            return False
        if parsed_path.path == (xhr_benchmark_helper_prefix + '_receive'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_receive_and_parse()
            return False
        if parsed_path.path == (xhr_benchmark_helper_prefix +
                                '_receive_getnocache'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_receive(int(parsed_path.query), False,
                                             False)
            return False
        if parsed_path.path == (xhr_benchmark_helper_prefix +
                                '_receive_getcache'):
            xhr_benchmark_handler = XHRBenchmarkHandler(
                self.headers, self.rfile, self.wfile)
            xhr_benchmark_handler.do_receive(int(parsed_path.query), False,
                                             True)
            return False

        host, port, resource = http_header_util.parse_uri(self.path)
        if resource is None:
            self._logger.info('Invalid URI: %r', self.path)
            self._logger.info('Fallback to CGIHTTPRequestHandler')
            return True
        server_options = self.server.websocket_server_options
        if host is not None:
            validation_host = server_options.validation_host
            if validation_host is not None and host != validation_host:
                self._logger.info('Invalid host: %r (expected: %r)', host,
                                  validation_host)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        if port is not None:
            validation_port = server_options.validation_port
            if validation_port is not None and port != validation_port:
                self._logger.info('Invalid port: %r (expected: %r)', port,
                                  validation_port)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        self.path = resource

        request = _StandaloneRequest(self, self._options.use_tls)

        try:
            # Fallback to default http handler for request paths for which
            # we don't have request handlers.
            if not self._options.dispatcher.get_handler_suite(self.path):
                self._logger.info('No handler for resource: %r', self.path)
                self._logger.info('Fallback to CGIHTTPRequestHandler')
                return True
        except dispatch.DispatchException as e:
            self._logger.info('Dispatch failed for error: %s', e)
            self.send_error(e.status)
            return False

        # If any Exceptions without except clause setup (including
        # DispatchException) is raised below this point, it will be caught
        # and logged by WebSocketServer.

        try:
            try:
                handshake.do_handshake(
                    request,
                    self._options.dispatcher,
                    allowDraft75=self._options.allow_draft75,
                    strict=self._options.strict)
            except handshake.VersionException as e:
                self._logger.info('Handshake failed for version error: %s', e)
                self.send_response(common.HTTP_STATUS_BAD_REQUEST)
                self.send_header(common.SEC_WEBSOCKET_VERSION_HEADER,
                                 e.supported_versions)
                self.end_headers()
                return False
            except handshake.HandshakeException as e:
                # Handshake for ws(s) failed.
                self._logger.info('Handshake failed for error: %s', e)
                self.send_error(e.status)
                return False

            request._dispatcher = self._options.dispatcher
            self._options.dispatcher.transfer_data(request)
        except handshake.AbortedByUserException as e:
            self._logger.info('Aborted: %s', e)
        return False
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.