示例#1
0
 def test_non_ssl_request(self):
     # Make sure the server closes the connection when it gets a non-ssl
     # connection, rather than waiting for a timeout or otherwise
     # misbehaving.
     with ExpectLog(gen_log, '(SSL Error|uncaught exception)'):
         with ExpectLog(gen_log, 'Uncaught exception', required=False):
             self.http_client.fetch(self.get_url("/").replace(
                 'https:', 'http:'),
                                    self.stop,
                                    request_timeout=3600,
                                    connect_timeout=3600)
             response = self.wait()
     self.assertEqual(response.code, 599)
 def test_chunked_with_content_length(self):
     # Make sure the invalid headers are detected
     with ExpectLog(gen_log,
                    ("Malformed HTTP message from None: Response "
                     "with both Transfer-Encoding and Content-Length")):
         response = self.fetch('/chunkwithcl')
     self.assertEqual(response.code, 599)
示例#3
0
    def test_connection_refused(self):
        # When a connection is refused, the connect callback should not
        # be run.  (The kqueue IOLoop used to behave differently from the
        # epoll IOLoop in this respect)
        cleanup_func, port = refusing_port()
        self.addCleanup(cleanup_func)
        stream = IOStream(socket.socket(), self.io_loop)
        self.connect_called = False

        def connect_callback():
            self.connect_called = True
            self.stop()
        stream.set_close_callback(self.stop)
        # log messages vary by platform and ioloop implementation
        with ExpectLog(gen_log, ".*", required=False):
            stream.connect(("127.0.0.1", port), connect_callback)
            self.wait()
        self.assertFalse(self.connect_called)
        self.assertTrue(isinstance(stream.error, socket.error), stream.error)
        if sys.platform != 'cygwin':
            _ERRNO_CONNREFUSED = (errno.ECONNREFUSED,)
            if hasattr(errno, "WSAECONNREFUSED"):
                _ERRNO_CONNREFUSED += (errno.WSAECONNREFUSED,)
            # cygwin's errnos don't match those used on native windows python
            self.assertTrue(stream.error.args[0] in _ERRNO_CONNREFUSED)
示例#4
0
    def test_read_until_regex_max_bytes(self):
        server, client = self.make_iostream_pair()
        client.set_close_callback(lambda: self.stop("closed"))
        try:
            # Extra room under the limit
            client.read_until_regex(b"def", self.stop, max_bytes=50)
            server.write(b"abcdef")
            data = self.wait()
            self.assertEqual(data, b"abcdef")

            # Just enough space
            client.read_until_regex(b"def", self.stop, max_bytes=6)
            server.write(b"abcdef")
            data = self.wait()
            self.assertEqual(data, b"abcdef")

            # Not enough space, but we don't know it until all we can do is
            # log a warning and close the connection.
            with ExpectLog(gen_log, "Unsatisfiable read"):
                client.read_until_regex(b"def", self.stop, max_bytes=5)
                server.write(b"123456")
                data = self.wait()
            self.assertEqual(data, "closed")
        finally:
            server.close()
            client.close()
示例#5
0
 def test_large_headers(self):
     with ExpectLog(gen_log, "Unsatisfiable read", required=False):
         response = self.fetch("/", headers={'X-Filler': 'a' * 1000})
     # 431 is "Request Header Fields Too Large", defined in RFC
     # 6585. However, many implementations just close the
     # connection in this case, resulting in a 599.
     self.assertIn(response.code, (431, 599))
示例#6
0
 def test_large_body_streaming_chunked(self):
     with ExpectLog(gen_log, '.*chunked body too large'):
         response = self.fetch(
             '/streaming',
             method='PUT',
             body_producer=lambda write: write(b'a' * 10240))
     self.assertEqual(response.code, 599)
示例#7
0
 def test_error_in_on_message(self):
     ws = yield self.ws_connect('/error_in_on_message')
     ws.write_message('hello')
     with ExpectLog(app_log, "Uncaught exception"):
         response = yield ws.read_message()
     self.assertIs(response, None)
     yield self.close(ws)
示例#8
0
 def test_gzip_unsupported(self):
     # Gzip support is opt-in; without it the server fails to parse
     # the body (but parsing form bodies is currently just a log message,
     # not a fatal error).
     with ExpectLog(gen_log, "Unsupported Content-Encoding"):
         response = self.post_gzip('foo=bar')
     self.assertEquals(json_decode(response.body), {})
示例#9
0
 def test_unix_socket_bad_request(self):
     # Unix sockets don't have remote addresses so they just return an
     # empty string.
     with ExpectLog(gen_log, "Malformed HTTP message from"):
         self.stream.write(b"garbage\r\n\r\n")
         self.stream.read_until_close(self.stop)
         response = self.wait()
     self.assertEqual(response, b"")
示例#10
0
 def test_websocket_network_fail(self):
     sock, port = bind_unused_port()
     sock.close()
     with self.assertRaises(IOError):
         with ExpectLog(gen_log, ".*"):
             yield websocket_connect('ws://127.0.0.1:%d/' % port,
                                     io_loop=self.io_loop,
                                     connect_timeout=3600)
示例#11
0
 def test_malformed_first_line(self):
     with ExpectLog(gen_log, '.*Malformed HTTP request line'):
         self.stream.write(b'asdf\r\n\r\n')
         # TODO: need an async version of ExpectLog so we don't need
         # hard-coded timeouts here.
         self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),
                                  self.stop)
         self.wait()
示例#12
0
 def test_error_logging(self):
     # No stack traces are logged for SSL errors.
     with ExpectLog(gen_log, 'SSL Error') as expect_log:
         self.http_client.fetch(
             self.get_url("/").replace("https:", "http:"), self.stop)
         response = self.wait()
         self.assertEqual(response.code, 599)
     self.assertFalse(expect_log.logged_stack)
示例#13
0
 def test_error_logging(self):
     # No stack traces are logged for SSL errors (in this case,
     # failure to validate the testing self-signed cert).
     # The SSLError is exposed through ssl.SSLError.
     with ExpectLog(gen_log, '.*') as expect_log:
         response = self.fetch("/", validate_cert=True)
         self.assertEqual(response.code, 599)
         self.assertIsInstance(response.error, ssl.SSLError)
     self.assertFalse(expect_log.logged_stack)
示例#14
0
 def test_exception_logging(self):
     """Uncaught exceptions get logged by the IOLoop."""
     # Use a NullContext to keep the exception from being caught by
     # AsyncTestCase.
     with NullContext():
         self.io_loop.add_callback(lambda: 1 / 0)
         self.io_loop.add_callback(self.stop)
         with ExpectLog(app_log, "Exception in callback"):
             self.wait()
示例#15
0
 def test_handshake_fail(self):
     server_future = self.server_start_tls(_server_ssl_options())
     # Certificates are verified with the default configuration.
     client_future = self.client_start_tls(server_hostname="localhost")
     with ExpectLog(gen_log, "SSL Error"):
         with self.assertRaises(ssl.SSLError):
             yield client_future
     with self.assertRaises((ssl.SSLError, socket.error)):
         yield server_future
示例#16
0
 def test_204_invalid_content_length(self):
     # 204 status with non-zero content length is malformed
     with ExpectLog(gen_log,
                    ".*Response with code 204 should not have body"):
         response = self.fetch("/?error=1")
         if not self.http1:
             self.skipTest("requires HTTP/1.x")
         if self.http_client.configured_class != SimpleAsyncHTTPClient:
             self.skipTest("curl client accepts invalid headers")
         self.assertEqual(response.code, 599)
示例#17
0
    def test_line_does_not_end_with_correct_line_break(self):
        data = b'''\
--1234
Content-Disposition: form-data; name="files"; filename="ab.txt"

Foo--1234--'''.replace(b"\n", b"\r\n")
        args = {}
        files = {}
        with ExpectLog(gen_log, "Invalid multipart/form-data"):
            parse_multipart_form_data(b"1234", data, args, files)
        self.assertEqual(files, {})
示例#18
0
    def test_missing_headers(self):
        data = b'''\
--1234

Foo
--1234--'''.replace(b"\n", b"\r\n")
        args = {}
        files = {}
        with ExpectLog(gen_log, "multipart/form-data missing headers"):
            parse_multipart_form_data(b"1234", data, args, files)
        self.assertEqual(files, {})
示例#19
0
 def test_unsupported_auth_mode(self):
     # curl and simple clients handle errors a bit differently; the
     # important thing is that they don't fall back to basic auth
     # on an unknown mode.
     with ExpectLog(gen_log, "uncaught exception", required=False):
         with self.assertRaises((ValueError, HTTPError)):
             response = self.fetch("/auth",
                                   auth_username="******",
                                   auth_password="******",
                                   auth_mode="asdf")
             response.rethrow()
示例#20
0
    def test_multiple_errors(self):
        def fail(message):
            raise Exception(message)

        self.io_loop.add_callback(lambda: fail("error one"))
        self.io_loop.add_callback(lambda: fail("error two"))
        # The first error gets raised; the second gets logged.
        with ExpectLog(app_log, "multiple unhandled exceptions"):
            with self.assertRaises(Exception) as cm:
                self.wait()
        self.assertEqual(str(cm.exception), "error one")
示例#21
0
    def test_invalid_content_length(self):
        with ExpectLog(gen_log, '.*Only integer Content-Length is allowed'):
            self.stream.write(b"""\
POST /echo HTTP/1.1
Content-Length: foo

bar

""".replace(b"\n", b"\r\n"))
            self.stream.read_until_close(self.stop)
            self.wait()
示例#22
0
    def test_invalid_content_disposition(self):
        data = b'''\
--1234
Content-Disposition: invalid; name="files"; filename="ab.txt"

Foo
--1234--'''.replace(b"\n", b"\r\n")
        args = {}
        files = {}
        with ExpectLog(gen_log, "Invalid multipart/form-data"):
            parse_multipart_form_data(b"1234", data, args, files)
        self.assertEqual(files, {})
示例#23
0
 def test_exception_logging_native_coro(self):
     """The IOLoop examines exceptions from awaitables and logs them."""
     namespace = exec_test(
         globals(), locals(), """
     async def callback():
         self.io_loop.add_callback(self.stop)
         1 / 0
     """)
     with NullContext():
         self.io_loop.add_callback(namespace["callback"])
         with ExpectLog(app_log, "Exception in callback"):
             self.wait()
示例#24
0
 def test_spawn_callback(self):
     # An added callback runs in the test's stack_context, so will be
     # re-arised in wait().
     self.io_loop.add_callback(lambda: 1 / 0)
     with self.assertRaises(ZeroDivisionError):
         self.wait()
     # A spawned callback is run directly on the IOLoop, so it will be
     # logged without stopping the test.
     self.io_loop.spawn_callback(lambda: 1 / 0)
     self.io_loop.add_callback(self.stop)
     with ExpectLog(app_log, "Exception in callback"):
         self.wait()
示例#25
0
    def test_content_disposition_header_without_name_parameter(self):
        data = b"""\
--1234
Content-Disposition: form-data; filename="ab.txt"

Foo
--1234--""".replace(b"\n", b"\r\n")
        args = {}
        files = {}
        with ExpectLog(gen_log, "multipart/form-data value missing name"):
            parse_multipart_form_data(b"1234", data, args, files)
        self.assertEqual(files, {})
示例#26
0
    def test_exception_logging_future(self):
        """The IOLoop examines exceptions from Futures and logs them."""
        with NullContext():

            @gen.coroutine
            def callback():
                self.io_loop.add_callback(self.stop)
                1 / 0

            self.io_loop.add_callback(callback)
            with ExpectLog(app_log, "Exception in callback"):
                self.wait()
示例#27
0
 def test_timeout(self):
     stream = IOStream(socket.socket())
     try:
         yield stream.connect(('127.0.0.1', self.get_http_port()))
         # Use a raw stream because AsyncHTTPClient won't let us read a
         # response without finishing a body.
         stream.write(b'PUT /streaming?body_timeout=0.1 HTTP/1.0\r\n'
                      b'Content-Length: 42\r\n\r\n')
         with ExpectLog(gen_log, 'Timeout reading body'):
             response = yield stream.read_until_close()
         self.assertEqual(response, b'')
     finally:
         stream.close()
示例#28
0
 def test_check_hostname(self):
     # Test that server_hostname parameter to start_tls is being used.
     # The check_hostname functionality is only available in python 2.7 and
     # up and in python 3.4 and up.
     server_future = self.server_start_tls(_server_ssl_options())
     client_future = self.client_start_tls(
         ssl.create_default_context(),
         server_hostname='127.0.0.1')
     with ExpectLog(gen_log, "SSL Error"):
         with self.assertRaises(ssl.SSLError):
             # The client fails to connect with an SSL error.
             yield client_future
     with self.assertRaises(Exception):
         # The server fails to connect, but the exact error is unspecified.
         yield server_future
示例#29
0
 def test_malformed_body(self):
     # parse_qs is pretty forgiving, but it will fail on python 3
     # if the data is not utf8.  On python 2 parse_qs will work,
     # but then the recursive_unicode call in EchoHandler will
     # fail.
     if str is bytes:
         return
     with ExpectLog(gen_log, 'Invalid x-www-form-urlencoded body'):
         response = self.fetch(
             '/echo',
             method="POST",
             headers={'Content-Type': 'application/x-www-form-urlencoded'},
             body=b'\xe9')
     self.assertEqual(200, response.code)
     self.assertEqual(b'{}', response.body)
示例#30
0
    def test_uncaught_exception_log(self):
        @gen.coroutine
        def f():
            yield gen.moment
            1 / 0

        g = f()

        with ExpectLog(
                app_log, "(?s)Future.* exception was never retrieved:"
                ".*ZeroDivisionError"):
            yield gen.moment
            yield gen.moment
            del g
            gc.collect()  # for PyPy