示例#1
0
    def test_multi_future_exceptions(self):
        with ExpectLog(app_log, "Multiple exceptions in yield list"):
            with self.assertRaises(RuntimeError) as cm:
                yield [self.async_exception(RuntimeError("error 1")),
                       self.async_exception(RuntimeError("error 2"))]
        self.assertEqual(str(cm.exception), "error 1")

        # With only one exception, no error is logged.
        with self.assertRaises(RuntimeError):
            yield [self.async_exception(RuntimeError("error 1")),
                   self.async_future(2)]

        # Exception logging may be explicitly quieted.
        with self.assertRaises(RuntimeError):
                yield gen.multi_future(
                    [self.async_exception(RuntimeError("error 1")),
                     self.async_exception(RuntimeError("error 2"))],
                    quiet_exceptions=RuntimeError)
示例#2
0
 def test_body_size_override_reset(self):
     # The max_body_size override is reset between requests.
     stream = IOStream(socket.socket())
     try:
         yield stream.connect(('127.0.0.1', self.get_http_port()))
         # Use a raw stream so we can make sure it's all on one connection.
         stream.write(b'PUT /streaming?expected_size=10240 HTTP/1.1\r\n'
                      b'Content-Length: 10240\r\n\r\n')
         stream.write(b'a' * 10240)
         headers, response = yield gen.Task(read_stream_body, stream)
         self.assertEqual(response, b'10240')
         # Without the ?expected_size parameter, we get the old default value
         stream.write(b'PUT /streaming HTTP/1.1\r\n'
                      b'Content-Length: 10240\r\n\r\n')
         with ExpectLog(gen_log, '.*Content-Length too long'):
             data = yield stream.read_until_close()
         self.assertEqual(data, b'')
     finally:
         stream.close()
示例#3
0
    def test_missing_headers(self, StreamingFormDataParserDelegateMock):
        delegate = StreamingFormDataParserDelegateMock()
        headers = HTTPHeaders()
        headers.add("Content-Type", 'multipart/form-data; boundary=1234')
        parser = StreamingFormDataParser(delegate, headers)
        data = b"""\
--1234


Foo
--1234--
        """.replace(b"\n", b"\r\n")

        with ExpectLog(gen_log, "multipart/form-data missing headers"):
            parser.data_received(data)

        self.assertFalse(delegate.start_file.called)
        self.assertFalse(delegate.finish_file.called)
        self.assertFalse(delegate.file_data_received.called)
示例#4
0
 def test_body_size_override_reset(self):
     # The max_body_size override is reset between requests.
     stream = IOStream(socket.socket())
     try:
         yield stream.connect(("10.0.0.7", self.get_http_port()))
         # Use a raw stream so we can make sure it's all on one connection.
         stream.write(b"PUT /streaming?expected_size=10240 HTTP/1.1\r\n"
                      b"Content-Length: 10240\r\n\r\n")
         stream.write(b"a" * 10240)
         start_line, headers, response = yield read_stream_body(stream)
         self.assertEqual(response, b"10240")
         # Without the ?expected_size parameter, we get the old default value
         stream.write(b"PUT /streaming HTTP/1.1\r\n"
                      b"Content-Length: 10240\r\n\r\n")
         with ExpectLog(gen_log, ".*Content-Length too long"):
             data = yield stream.read_until_close()
         self.assertEqual(data, b"HTTP/1.1 400 Bad Request\r\n\r\n")
     finally:
         stream.close()
示例#5
0
    def test_connection_refused(self):
        cleanup_func, port = refusing_port()
        self.addCleanup(cleanup_func)
        with ExpectLog(gen_log, ".*", required=False):
            self.http_client.fetch("http://127.0.0.1:%d/" % port, self.stop)
            response = self.wait()
        self.assertEqual(599, response.code)

        if sys.platform != 'cygwin':
            # cygwin returns EPERM instead of ECONNREFUSED here
            contains_errno = str(errno.ECONNREFUSED) in str(response.error)
            if not contains_errno and hasattr(errno, "WSAECONNREFUSED"):
                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)
            self.assertTrue(contains_errno, response.error)
            # This is usually "Connection refused".
            # On windows, strerror is broken and returns "Unknown error".
            expected_message = os.strerror(errno.ECONNREFUSED)
            self.assertTrue(expected_message in str(response.error),
                            response.error)
示例#6
0
    def test_exception_in_last(self):
        def callback2():
            raise Exception('callback1 error')

        def finish_callback():
            self.fail('finish_callback should not be called')

        ag = AsyncGroup(finish_callback, name='test_group')
        cb1 = ag.add(lambda: None)
        cb2 = ag.add(callback2)

        cb1()

        with ExpectLog(
                async_logger,
                r'.*aborting AsyncGroup\(name=test_group, finished=False\)'):
            self.assertRaises(Exception, cb2)

        self.assertEqual(ag._finished, True)
示例#7
0
    def test_connection_refused(self: typing.Any):
        cleanup_func, port = refusing_port()
        self.addCleanup(cleanup_func)
        with ExpectLog(gen_log, ".*", required=False):
            with self.assertRaises(socket.error) as cm:
                self.fetch("http://127.0.0.1:%d/" % port, raise_error=True)

        if sys.platform != "cygwin":
            # cygwin returns EPERM instead of ECONNREFUSED here
            contains_errno = str(errno.ECONNREFUSED) in str(cm.exception)
            if not contains_errno and hasattr(errno, "WSAECONNREFUSED"):
                contains_errno = str(errno.WSAECONNREFUSED) in str(  # type: ignore
                    cm.exception
                )
            self.assertTrue(contains_errno, cm.exception)
            # This is usually "Connection refused".
            # On windows, strerror is broken and returns "Unknown error".
            expected_message = os.strerror(errno.ECONNREFUSED)
            self.assertTrue(expected_message in str(cm.exception), cm.exception)
示例#8
0
    def test_ipv6(self):
        try:
            self.http_server.listen(self.get_http_port(), address='::1')
        except socket.gaierror as e:
            if e.args[0] == socket.EAI_ADDRFAMILY:
                # python supports ipv6, but it's not configured on the network
                # interface, so skip this test.
                return
            raise
        url = self.get_url("/hello").replace("localhost", "[::1]")

        # ipv6 is currently disabled by default and must be explicitly requested
        with ExpectLog(gen_log, "uncaught exception"):
            self.http_client.fetch(url, self.stop)
            response = self.wait()
        self.assertEqual(response.code, 599)

        self.http_client.fetch(url, self.stop, allow_ipv6=True)
        response = self.wait()
        self.assertEqual(response.body, b"Hello world!")
示例#9
0
 def test_async_read_error_logging(self):
     # Socket errors on asynchronous reads should be logged (but only
     # once).
     server, client = self.make_iostream_pair()
     server.set_close_callback(self.stop)
     try:
         # Start a read that will be fullfilled asynchronously.
         server.read_bytes(1, lambda data: None)
         client.write(b('a'))
         # Stub out read_from_fd to make it fail.
         def fake_read_from_fd():
             os.close(server.socket.fileno())
             server.__class__.read_from_fd(server)
         server.read_from_fd = fake_read_from_fd
         # This log message is from _handle_read (not read_from_fd).
         with ExpectLog(gen_log, "error on read"):
             self.wait()
     finally:
         server.close()
         client.close()
示例#10
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)
        server_socket, port = bind_unused_port()
        server_socket.close()
        stream = IOStream(socket.socket(), self.io_loop)
        self.connect_called = False

        def connect_callback():
            self.connect_called = True
        stream.set_close_callback(self.stop)
        # log messages vary by platform and ioloop implementation
        with ExpectLog(gen_log, ".*", required=False):
            stream.connect(("localhost", port), connect_callback)
            self.wait()
        self.assertFalse(self.connect_called)
        self.assertTrue(isinstance(stream.error, socket.error), stream.error)
        if sys.platform != 'cygwin':
            # cygwin's errnos don't match those used on native windows python
            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)
示例#11
0
    def test_invalid_content_disposition(self,
                                         StreamingFormDataParserDelegateMock):
        delegate = StreamingFormDataParserDelegateMock()
        headers = HTTPHeaders()
        headers.add("Content-Type", 'multipart/form-data; boundary=1234')
        parser = StreamingFormDataParser(delegate, headers)
        data = b"""\
--1234
Content-Disposition: invalid; name="files"; filename="ab.txt"


Foo
--1234--
        """.replace(b"\n", b"\r\n")

        with ExpectLog(gen_log, "Invalid multipart/form-data"):
            parser.data_received(data)

        self.assertFalse(delegate.start_file.called)
        self.assertFalse(delegate.finish_file.called)
        self.assertFalse(delegate.file_data_received.called)
示例#12
0
    def test_exception_in_last(self):
        def callback2():
            raise Exception('callback1 error')

        def finish_callback():
            self.fail('finish_callback should not be called')

        ag = AsyncGroup(finish_callback, name='test_group')
        cb1 = ag.add(lambda: None)
        cb2 = ag.add(callback2)

        cb1()

        with ExpectLog(
                async_logger,
                '.*test_group group: aborting async group due to unhandled exception in callback'
        ):
            self.assertRaises(Exception, cb2)

        self.assertEqual(ag._finish_cb_called, False)
        self.assertEqual(ag._aborted, True)
示例#13
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())

        stream.set_close_callback(self.stop)
        # log messages vary by platform and ioloop implementation
        with ExpectLog(gen_log, ".*", required=False):
            with self.assertRaises(StreamClosedError):
                yield stream.connect(("127.0.0.1", port))

        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)
示例#14
0
    def test_notifications(self):
        f = Future()
        ag = AsyncGroup(partial(f.set_result, True))
        not1 = ag.add_notification()
        not2 = ag.add_notification()

        self.assertEqual(ag._finished, False)

        not1()

        self.assertEqual(ag._finished, False)

        not2('params', are='ignored')

        self.assertEqual(ag._finished, True)
        self.assertEqual(f.result(), True)

        with ExpectLog(
                async_logger,
                r'.*trying to finish already finished AsyncGroup\(name=None, finished=True\)'
        ):
            ag.finish()
示例#15
0
 def test_cookie_tampering_future_timestamp(self):
     handler = CookieTestRequestHandler()
     # this string base64-encodes to '12345678'
     handler.set_secure_cookie('foo', binascii.a2b_hex(b'd76df8e7aefc'))
     cookie = handler._cookies['foo']
     match = re.match(br'12345678\|([0-9]+)\|([0-9a-f]+)', cookie)
     self.assertTrue(match)
     timestamp = match.group(1)
     sig = match.group(2)
     self.assertEqual(
         _create_signature(handler.application.settings["cookie_secret"],
                           'foo', '12345678', timestamp), sig)
     # shifting digits from payload to timestamp doesn't alter signature
     # (this is not desirable behavior, just confirming that that's how it
     # works)
     self.assertEqual(
         _create_signature(handler.application.settings["cookie_secret"],
                           'foo', '1234', b'5678' + timestamp), sig)
     # tamper with the cookie
     handler._cookies['foo'] = utf8(
         '1234|5678%s|%s' % (to_basestring(timestamp), to_basestring(sig)))
     # it gets rejected
     with ExpectLog(gen_log, "Cookie timestamp in future"):
         self.assertTrue(handler.get_secure_cookie('foo') is None)
示例#16
0
    def test_exception_in_first(self):
        def callback1():
            raise Exception('callback1 error')

        def callback2():
            self.fail('callback2 should not be called')

        def finish_callback():
            self.fail('finish_callback should not be called')

        ag = AsyncGroup(finish_callback, name='test_group')
        cb1 = ag.add(callback1)
        cb2 = ag.add(callback2)

        self.assertRaises(Exception, cb1)
        self.assertEqual(ag._finished, True)

        with ExpectLog(
                async_logger,
                r'.*ignoring executing callback in AsyncGroup\(name=test_group, finished=True\)'
        ):
            cb2()

        self.assertEqual(ag._finished, True)
示例#17
0
    def test_uncaught_exception_log(self):
        if IOLoop.configured_class().__name__.endswith('AsyncIOLoop'):
            # Install an exception handler that mirrors our
            # non-asyncio logging behavior.
            def exc_handler(loop, context):
                app_log.error('%s: %s', context['message'],
                              type(context.get('exception')))

            self.io_loop.asyncio_loop.set_exception_handler(exc_handler)

        @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
示例#18
0
 def test_error_in_async_open(self):
     with ExpectLog(app_log, "Uncaught exception"):
         ws = yield self.ws_connect("/error_in_async_open")
         res = yield ws.read_message()
     self.assertIsNone(res)
示例#19
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)
 def test_stack_context(self):
     with ExpectLog(app_log, "Uncaught exception GET /"):
         self.http_client.fetch(self.get_url('/'), self.handle_response)
         self.wait()
     self.assertEqual(self.response.code, 500)
     self.assertTrue(b'got expected exception' in self.response.body)
示例#21
0
 def test_twitter_show_user_error_legacy(self):
     with ExpectLog(gen_log, 'Error response HTTP 500'):
         response = self.fetch(
             '/legacy/twitter/client/show_user?name=error')
     self.assertEqual(response.code, 500)
     self.assertEqual(response.body, b'error from twitter request')
示例#22
0
 def test_coroutine_exception_handler(self):
     # Make sure we get an error and not a timeout
     with ExpectLog(app_log, "Uncaught exception GET /coroutine_exception"):
         response = self.fetch('/coroutine_exception')
     self.assertEqual(500, response.code)
示例#23
0
 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)
示例#24
0
 def test_large_body(self):
     with ExpectLog(gen_log, "Malformed HTTP message from None: Content-Length too long"):
         response = self.fetch('/large')
     self.assertEqual(response.code, 599)
示例#25
0
 def test_ssl_context_handshake_fail(self):
     with ExpectLog(gen_log, "SSL Error|Uncaught exception"):
         ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
         ctx.verify_mode = ssl.CERT_REQUIRED
         resp = self.fetch("/hello", ssl_options=ctx)
     self.assertRaises(ssl.SSLError, resp.rethrow)
 def test_large_headers(self):
     with ExpectLog(gen_log, "Unsatisfiable read"):
         response = self.fetch('/large')
     self.assertEqual(response.code, 599)
示例#27
0
 def test_large_body_streaming(self):
     with ExpectLog(gen_log, ".*Content-Length too long"):
         response = self.fetch("/streaming",
                               method="PUT",
                               body=b"a" * 10240)
     self.assertEqual(response.code, 400)
示例#28
0
 def test_large_headers(self):
     with ExpectLog(gen_log, "Unsatisfiable read"):
         with self.assertRaises(UnsatisfiableReadError):
             self.fetch('/large', raise_error=True)
示例#29
0
 def test_large_body(self):
     with ExpectLog(
             gen_log,
             "Malformed HTTP message from None: Content-Length too long"):
         with self.assertRaises(HTTPStreamClosedError):
             self.fetch('/large', raise_error=True)
示例#30
0
 def test_ssl_options_handshake_fail(self):
     with ExpectLog(gen_log, "SSL Error|Uncaught exception",
                    required=False):
         resp = self.fetch(
             "/hello", ssl_options=dict(cert_reqs=ssl.CERT_REQUIRED))
     self.assertRaises(ssl.SSLError, resp.rethrow)