Ejemplo n.º 1
0
    def init_request_handler(self, rh_cls, view_type):
        global app
        if view_type == 'list':
            rq = rh_cls.as_list()
        elif view_type == 'detail':
            rq = rh_cls.as_detail()

        # compose a fake incoming request
        fake_connection = None

        # after tornado 4.1, it's not allowed to build a RequestHandler without a connection.
        if _newer_or_equal_((4, 0, 0, 0)):
            ios = IOStream(socket.socket(socket.AF_INET, socket.SOCK_STREAM,
                                         0))
            context = None

            # there is a bug in these 2 version that would fail when
            # context is None
            if _equal_((4, 0, 1)) or _equal_((4, 0, 2)):
                context = httpserver._HTTPRequestContext(ios, None, None)
            fake_connection = HTTP1Connection(ios, False, context=context)
        fake_request = httpserver.HTTPRequest('GET',
                                              '/fake',
                                              body='test123',
                                              connection=fake_connection)
        self.new_handler = rq(app, fake_request)
Ejemplo n.º 2
0
def test_no_connection_reuse_with_connection_close(server, io_stream):
    '''Sends '/ping' request to the server with 'Connection: Close' and validate
    that the connection is closed by the server.

    To check that the server closes the connection, read all the data from the
    socket. If the server fails to close the socket, the test will hang for the
    specified async_test's timeout.

    Args:
        server: an instance of `Server`.
        io_stream: an instance of `tornado.iostream.IOStream`.
    '''

    yield io_stream.connect(('localhost', server.opts['port']))

    start_line = RequestStartLine(method='GET',
                                  path='/ping',
                                  version='HTTP/1.1')
    headers = HTTPHeaders({'Connection': 'Close'})

    connection = HTTP1Connection(io_stream, is_client=True)
    yield connection.write_headers(start_line, headers)
    connection.finish()

    response = PingResponseHandler()
    yield connection.read_response(response)

    assert response.start_line.code == requests.codes.ok

    # read all remaining data from the connection and validate it (there should be no data)
    remaining_data = yield io_stream.read_until_close()
    assert len(remaining_data) == 0
Ejemplo n.º 3
0
    def test_http10_no_content_length(self):
        # Regression test for a bug in which can_keep_alive would crash
        # for an HTTP/1.0 (not 1.1) response with no content-length.
        conn = HTTP1Connection(self.client_stream, True)
        self.server_stream.write(b"HTTP/1.0 200 Not Modified\r\n\r\nhello")
        self.server_stream.close()

        event = Event()
        test = self
        body = []

        class Delegate(HTTPMessageDelegate):
            def headers_received(self, start_line, headers):
                test.code = start_line.code

            def data_received(self, data):
                body.append(data)

            def finish(self):
                event.set()

        yield conn.read_response(Delegate())
        yield event.wait()
        self.assertEqual(self.code, 200)
        self.assertEqual(b''.join(body), b'hello')
Ejemplo n.º 4
0
def test_connection_reuse_for_HTTP_1_1(server, io_stream, num_requests):
    '''Sends multiple '/ping' requests to the server using the same connection.

    The ok handler that just responds with 200 is used for serving requests.
    Keep-Alive is assumed by default for each request as it's HTTP/1.1.

    Args:
        server: an instance of `Server`.
        io_stream:
            an instance of `tornado.iostream.IOStream` that is used for
            consecutive requests.
    '''

    yield io_stream.connect(('localhost', server.opts['port']))

    # common request start line and headers for all ping requests
    start_line = RequestStartLine(method='GET',
                                  path='/ping',
                                  version='HTTP/1.1')
    headers = HTTPHeaders()

    for request in range(num_requests):
        connection = HTTP1Connection(io_stream, is_client=True)
        yield connection.write_headers(start_line, headers)
        connection.finish()

        response = PingResponseHandler()
        yield connection.read_response(response)

        assert response.start_line.code == requests.codes.ok
Ejemplo n.º 5
0
async def main(stream):
    print(stream)
    chunks = []

    class Delegate(HTTPMessageDelegate):
        def headers_received(self, start_line, headers):
            self.headers = headers
            self.start_line = start_line
            print('headers_received')

        def data_received(self, chunk):
            chunks.append(chunk)
            print('data_received')

        def finish(self):
            conn.detach()  # type: ignore
            print('finish')

    stream = IOStream(stream)
    #print('ideme connect')
    #await stream.connect(("example.com", 80))
    print('await stream.connect(("example.com", 80))')
    await stream.write(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
    print('await stream.write(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")')
    conn = HTTP1Connection(stream, True)
    delegate = Delegate()
    await conn.read_response(delegate)
    print(delegate.start_line, delegate.headers, b"".join(chunks))
Ejemplo n.º 6
0
 def _create_connection(self, stream):
     stream.set_nodelay(True)
     connection = HTTP1Connection(
         stream, True,
         HTTP1ConnectionParameters(
             no_keep_alive=True,
             max_header_size=self.max_header_size,
             decompress=self.request.decompress_response), self._sockaddr)
     return connection
Ejemplo n.º 7
0
def http_connection(request, io_stream):
    '''Create an instance of the `tornado.http1connection.HTTP1Connection`.

    `io_stream` fixture will be used for the connection.
    '''
    opts = request.node.get_marker('http_connection_options')
    opts = opts.kwargs if opts else {}
    params = HTTP1ConnectionParameters(**opts)

    return HTTP1Connection(
        io_stream,
        is_client=True,
        params=params,
    )
Ejemplo n.º 8
0
def read_stream_body(stream, callback):
    """Reads an HTTP response from `stream` and runs callback with its
    headers and body."""
    chunks = []
    class Delegate(HTTPMessageDelegate):
        def headers_received(self, start_line, headers):
            self.headers = headers

        def data_received(self, chunk):
            chunks.append(chunk)

        def finish(self):
            callback((self.headers, b''.join(chunks)))
    conn = HTTP1Connection(stream, True)
    conn.read_response(Delegate())
Ejemplo n.º 9
0
 def handle_stream(self, ssl_stream, address):
     try:
         yield ssl_stream.wait_for_handshake()
     except SSLErrorHTTPRequest:
         stream = IOStream(ssl_stream.socket._sock)
         conn = HTTP1Connection(stream, is_client=False)
         try:
             yield self.handle_http_connection(conn)
         except Exception:
             logger.exception("Failed to process HTTP request:")
         finally:
             stream.close()
     except StreamClosedError:
         logger.debug("Stream closed by client during handshake. Skipping.")
         return
     else:
         super(AutoHTTPSServer, self).handle_stream(ssl_stream, address)
Ejemplo n.º 10
0
async def read_stream_body(stream):
    """Reads an HTTP response from `stream` and returns a tuple of its
    start_line, headers and body."""
    chunks = []

    class Delegate(HTTPMessageDelegate):
        def headers_received(self, start_line, headers):
            self.headers = headers
            self.start_line = start_line

        def data_received(self, chunk):
            chunks.append(chunk)

        def finish(self):
            conn.detach()  # type: ignore

    conn = HTTP1Connection(stream, True)
    delegate = Delegate()
    await conn.read_response(delegate)
    return delegate.start_line, delegate.headers, b"".join(chunks)
Ejemplo n.º 11
0
 def handle_stream(self, ssl_stream, address):
     try:
         yield ssl_stream.wait_for_handshake()
     except SSLErrorHTTPRequest:
         stream = make_iostream(ssl_stream)
         conn = HTTP1Connection(stream, is_client=False)
         try:
             yield self.handle_http_connection(conn)
         except Exception:
             logger.exception("Failed to process HTTP request:")
         finally:
             stream.close()
     except ssl.SSLError as e:
         logger.error("SSLError: %s", e)
     except (OSError, StreamClosedError) as e:
         logger.debug("Error during SSL handshake: %s %s",
                      e.__class__.__name__, getattr(e, "strerror", str(e)))
         logger.debug("Stream closed by client during handshake. Skipping.")
         return
     else:
         super(AutoHTTPSServer, self).handle_stream(ssl_stream, address)
Ejemplo n.º 12
0
 def setUp(self):
     super(TestWebSocketBase, self).setUp()
     self.application = Application()
     self.server = HTTPServer(self.application)
     self.socket, self.port = testing.bind_unused_port()
     self.server.add_socket(self.socket)
     self.instance = WebSocketBase(
         self.application,
         HTTPServerRequest(
             method="GET",
             uri='/',
             version="HTTP/1.0",
             headers=HTTPHeaders(),
             body=BytesIO(),
             host=None,
             files=None,
             connection=HTTP1Connection(stream=IOStream(socket.socket()),
                                        is_client=False),
             start_line=RequestStartLine(method='GET',
                                         path='/',
                                         version='HTTP/1.1'),
         ))
     self.instance.open()
Ejemplo n.º 13
0
async def read_stream_body(stream):
    """Reads an HTTP response from `stream` and returns a tuple of its
    start_line, headers and body."""

    chunks = []

    class Delegate(HTTPMessageDelegate):
        def headers_received(self, start_line, headers):
            self.headers = headers
            self.start_line = start_line
            print('headers_received')

        def data_received(self, chunk):
            chunks.append(chunk)
            print('data_received')

        def finish(self):
            conn.detach()  # type: ignore
            print('finish')

    conn = HTTP1Connection(stream, True)
    print('conn = HTTP1Connection(stream, True)')
    delegate = Delegate()
    print('delegate = Delegate()')
Ejemplo n.º 14
0
 def __init__(self, host, port):
     self._sock = socket()
     self._sock.connect((host, port))
     self._stream = IOStream(self._sock)
     self._connection = HTTP1Connection(self._stream, True)
Ejemplo n.º 15
0
 def __init__(self, stream, params=None):
     HTTP1Connection.__init__(self, stream, True, params)
Ejemplo n.º 16
0
        def __init__(self, stream):
            self.stream = stream
            self.connection = HTTP1Connection(stream, is_client=True)

            self.response_start_line = None
            self.response_headers = None
Ejemplo n.º 17
0
 def _on_connect(self, stream):
     if self.final_callback is None:
         # final_callback is cleared if we've hit our timeout.
         stream.close()
         return
     self.stream = stream
     self.stream.set_close_callback(self._on_close)
     self._remove_timeout()
     if self.final_callback is None:
         return
     if self.request.request_timeout:
         self._timeout = self.io_loop.add_timeout(
             self.start_time + self.request.request_timeout,
             stack_context.wrap(self._on_timeout))
     if (self.request.method not in self._SUPPORTED_METHODS
             and not self.request.allow_nonstandard_methods):
         raise KeyError("unknown method %s" % self.request.method)
     for key in ('network_interface', 'proxy_host', 'proxy_port',
                 'proxy_username', 'proxy_password'):
         if getattr(self.request, key, None):
             raise NotImplementedError('%s not supported' % key)
     if "Connection" not in self.request.headers:
         self.request.headers["Connection"] = "close"
     if "Host" not in self.request.headers:
         if '@' in self.parsed.netloc:
             self.request.headers["Host"] = self.parsed.netloc.rpartition(
                 '@')[-1]
         else:
             self.request.headers["Host"] = self.parsed.netloc
     username, password = None, None
     if self.parsed.username is not None:
         username, password = self.parsed.username, self.parsed.password
     elif self.request.auth_username is not None:
         username = self.request.auth_username
         password = self.request.auth_password or ''
     if username is not None:
         if self.request.auth_mode not in (None, "basic"):
             raise ValueError("unsupported auth_mode %s",
                              self.request.auth_mode)
         auth = utf8(username) + b":" + utf8(password)
         self.request.headers["Authorization"] = (b"Basic " +
                                                  base64.b64encode(auth))
     if self.request.user_agent:
         self.request.headers["User-Agent"] = self.request.user_agent
     if not self.request.allow_nonstandard_methods:
         if self.request.method in ("POST", "PATCH", "PUT"):
             if (self.request.body is None
                     and self.request.body_producer is None):
                 raise AssertionError(
                     'Body must not be empty for "%s" request' %
                     self.request.method)
         else:
             if (self.request.body is not None
                     or self.request.body_producer is not None):
                 raise AssertionError(
                     'Body must be empty for "%s" request' %
                     self.request.method)
     if self.request.expect_100_continue:
         self.request.headers["Expect"] = "100-continue"
     if self.request.body is not None:
         # When body_producer is used the caller is responsible for
         # setting Content-Length (or else chunked encoding will be used).
         self.request.headers["Content-Length"] = str(len(
             self.request.body))
     if (self.request.method == "POST"
             and "Content-Type" not in self.request.headers):
         self.request.headers[
             "Content-Type"] = "application/x-www-form-urlencoded"
     if self.request.decompress_response:
         self.request.headers["Accept-Encoding"] = "gzip"
     req_path = ((self.parsed.path or '/') +
                 (('?' + self.parsed.query) if self.parsed.query else ''))
     self.stream.set_nodelay(True)
     self.connection = HTTP1Connection(
         self.stream, True,
         HTTP1ConnectionParameters(
             no_keep_alive=True,
             max_header_size=self.max_header_size,
             decompress=self.request.decompress_response), self._sockaddr)
     start_line = httputil.RequestStartLine(self.request.method, req_path,
                                            'HTTP/1.1')
     self.connection.write_headers(start_line, self.request.headers)
     if self.request.expect_100_continue:
         self._read_response()
     else:
         self._write_body(True)
Ejemplo n.º 18
0
        def create_qactuar_handler(self, scope: Scope) -> RequestHandler:
            # noinspection PyAbstractClass,PyMethodParameters
            class QactuarHandler(self.handler_type):  # type: ignore
                def __init__(
                    inner_self,
                    tornado_application: Application,
                    tornado_request: HTTPServerRequest,
                    logger: Logger,
                    **kwargs: Dict[Any, Any],
                ) -> None:
                    super().__init__(tornado_application, tornado_request,
                                     **kwargs)
                    inner_self._qactuar_body: List[bytes] = []
                    inner_self._qactuar_headers: Headers = []
                    inner_self._logger = logger

                def write(inner_self, chunk: Union[str, bytes, dict]) -> None:
                    super().write(chunk)
                    inner_self._qactuar_body.append(to_bytes(chunk))

                def add_header(inner_self, name: str,
                               value: _HeaderTypes) -> None:
                    super().add_header(name, value)
                    inner_self._qactuar_headers.append(
                        (to_bytes(name), to_bytes(value)))

                def set_header(inner_self, name: str,
                               value: _HeaderTypes) -> None:
                    super().set_header(name, value)
                    inner_self._qactuar_headers.append(
                        (to_bytes(name), to_bytes(value)))

            if self.request_message and "body" in self.request_message:
                body = self.request_message["body"]
            else:
                body = b""
            if self.request_message and "headers" in self.request_message:
                headers = scope["headers"]
            else:
                headers = []
            headers = HTTPHeaders({
                header[0].decode("utf-8"): header[1].decode("utf-8")
                for header in headers
            })
            request_start_line = RequestStartLine(scope["method"],
                                                  scope["path"],
                                                  scope["http_version"])

            # noinspection PyTypeChecker
            http_connection = HTTP1Connection(QactuarStream(), False)
            http_connection._request_start_line = request_start_line
            http_connection._request_headers = headers

            request = HTTPServerRequest(
                method=scope["method"],
                uri=scope["path"],
                version=scope["http_version"],
                headers=headers,
                body=body,
                host=scope["server"][0],
                connection=http_connection,
                start_line=request_start_line,
            )

            handler = QactuarHandler(Application(), request, self.child_log)
            handler._transforms = []
            handler.application.transforms = []

            return handler