.. module:: tornado.curl_httpclient
-.. class:: CurlAsyncHTTPClient(io_loop, max_clients=10, defaults=None)
+.. class:: CurlAsyncHTTPClient(max_clients=10, defaults=None)
``libcurl``-based HTTP client.
_io_loops = weakref.WeakKeyDictionary() # type: ignore
-def start(io_loop=None, check_time=500):
+def start(check_time=500):
"""Begins watching source files for changes.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- io_loop = io_loop or ioloop.IOLoop.current()
+ io_loop = ioloop.IOLoop.current()
if io_loop in _io_loops:
return
_io_loops[io_loop] = True
gen_log.warning("tornado.autoreload started more than once in the same process")
modify_times = {}
callback = functools.partial(_reload_on_update, modify_times)
- scheduler = ioloop.PeriodicCallback(callback, check_time, io_loop=io_loop)
+ scheduler = ioloop.PeriodicCallback(callback, check_time)
scheduler.start()
class CurlAsyncHTTPClient(AsyncHTTPClient):
- def initialize(self, io_loop, max_clients=10, defaults=None):
- super(CurlAsyncHTTPClient, self).initialize(io_loop, defaults=defaults)
+ def initialize(self, max_clients=10, defaults=None):
+ super(CurlAsyncHTTPClient, self).initialize(defaults=defaults)
self._multi = pycurl.CurlMulti()
self._multi.setopt(pycurl.M_TIMERFUNCTION, self._set_timeout)
self._multi.setopt(pycurl.M_SOCKETFUNCTION, self._handle_socket)
# SOCKETFUNCTION. Mitigate the effects of such bugs by
# forcing a periodic scan of all active requests.
self._force_timeout_callback = ioloop.PeriodicCallback(
- self._handle_force_timeout, 1000, io_loop=io_loop)
+ self._handle_force_timeout, 1000)
self._force_timeout_callback.start()
# Work around a bug in libcurl 7.29.0: Some fields in the curl
class YieldFuture(YieldPoint):
- def __init__(self, future, io_loop=None):
+ def __init__(self, future):
"""Adapts a `.Future` to the `YieldPoint` interface.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
self.future = future
- self.io_loop = io_loop or IOLoop.current()
+ self.io_loop = IOLoop.current()
def start(self, runner):
if not self.future.done():
return fut
-def with_timeout(timeout, future, io_loop=None, quiet_exceptions=()):
+def with_timeout(timeout, future, quiet_exceptions=()):
"""Wraps a `.Future` (or other yieldable object) in a timeout.
Raises `TimeoutError` if the input future does not complete before
future = convert_yielded(future)
result = Future()
chain_future(future, result)
- if io_loop is None:
- io_loop = IOLoop.current()
+ io_loop = IOLoop.current()
def error_callback(future):
try:
header_data = yield gen.with_timeout(
self.stream.io_loop.time() + self.params.header_timeout,
header_future,
- io_loop=self.stream.io_loop,
quiet_exceptions=iostream.StreamClosedError)
except gen.TimeoutError:
self.close()
try:
yield gen.with_timeout(
self.stream.io_loop.time() + self._body_timeout,
- body_future, self.stream.io_loop,
+ body_future,
quiet_exceptions=iostream.StreamClosedError)
except gen.TimeoutError:
gen_log.info("Timeout reading body from %s",
from tornado.concurrent import TracebackFuture
from tornado.escape import utf8, native_str
-from tornado import httputil, stack_context
+from tornado import gen, httputil, stack_context
from tornado.ioloop import IOLoop
from tornado.util import Configurable
self._io_loop = IOLoop(make_current=False)
if async_client_class is None:
async_client_class = AsyncHTTPClient
- self._async_client = async_client_class(self._io_loop, **kwargs)
+ # Create the client while our IOLoop is "current", without
+ # clobbering the thread's real current IOLoop (if any).
+ self._async_client = self._io_loop.run_sync(
+ gen.coroutine(lambda: async_client_class(**kwargs)))
self._closed = False
def __del__(self):
The constructor for this class is magic in several respects: It
actually creates an instance of an implementation-specific
subclass, and instances are reused as a kind of pseudo-singleton
- (one per `.IOLoop`). The keyword argument ``force_instance=True``
- can be used to suppress this singleton behavior. Unless
- ``force_instance=True`` is used, no arguments other than
- ``io_loop`` should be passed to the `AsyncHTTPClient` constructor.
- The implementation subclass as well as arguments to its
- constructor can be set with the static method `configure()`
+ (one per `.IOLoop`). The keyword argument ``force_instance=True``
+ can be used to suppress this singleton behavior. Unless
+ ``force_instance=True`` is used, no arguments should be passed to
+ the `AsyncHTTPClient` constructor. The implementation subclass as
+ well as arguments to its constructor can be set with the static
+ method `configure()`
All `AsyncHTTPClient` implementations support a ``defaults``
keyword argument, which can be used to set default values for
client = AsyncHTTPClient(force_instance=True,
defaults=dict(user_agent="MyUserAgent"))
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
+
"""
@classmethod
def configurable_base(cls):
setattr(cls, attr_name, weakref.WeakKeyDictionary())
return getattr(cls, attr_name)
- def __new__(cls, io_loop=None, force_instance=False, **kwargs):
- io_loop = io_loop or IOLoop.current()
+ def __new__(cls, force_instance=False, **kwargs):
+ io_loop = IOLoop.current()
if force_instance:
instance_cache = None
else:
instance_cache = cls._async_clients()
if instance_cache is not None and io_loop in instance_cache:
return instance_cache[io_loop]
- instance = super(AsyncHTTPClient, cls).__new__(cls, io_loop=io_loop,
- **kwargs)
+ instance = super(AsyncHTTPClient, cls).__new__(cls, **kwargs)
# Make sure the instance knows which cache to remove itself from.
# It can't simply call _async_clients() because we may be in
# __new__(AsyncHTTPClient) but instance.__class__ may be
instance_cache[instance.io_loop] = instance
return instance
- def initialize(self, io_loop, defaults=None):
- self.io_loop = io_loop
+ def initialize(self, defaults=None):
+ self.io_loop = IOLoop.current()
self.defaults = dict(HTTPRequest._DEFAULTS)
if defaults is not None:
self.defaults.update(defaults)
.. versionchanged:: 4.5
Added the ``trusted_downstream`` argument.
+
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument has been removed.
"""
def __init__(self, *args, **kwargs):
# Ignore args to __init__; real initialization belongs in
# completely)
pass
- def initialize(self, request_callback, no_keep_alive=False, io_loop=None,
+ def initialize(self, request_callback, no_keep_alive=False,
xheaders=False, ssl_options=None, protocol=None,
decompress_request=False,
chunk_size=None, max_header_size=None,
max_body_size=max_body_size,
body_timeout=body_timeout,
no_keep_alive=no_keep_alive)
- TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,
+ TCPServer.__init__(self, ssl_options=ssl_options,
max_buffer_size=max_buffer_size,
read_chunk_size=chunk_size)
self._connections = set()
`start` must be called after the `PeriodicCallback` is created.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- def __init__(self, callback, callback_time, io_loop=None):
+ def __init__(self, callback, callback_time):
self.callback = callback
if callback_time <= 0:
raise ValueError("Periodic callback must have a positive callback_time")
self.callback_time = callback_time
- self.io_loop = io_loop or IOLoop.current()
+ self.io_loop = IOLoop.current()
self._running = False
self._timeout = None
Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,
`read_from_fd`, and optionally `get_fd_error`.
"""
- def __init__(self, io_loop=None, max_buffer_size=None,
+ def __init__(self, max_buffer_size=None,
read_chunk_size=None, max_write_buffer_size=None):
"""`BaseIOStream` constructor.
- :arg io_loop: The `.IOLoop` to use; defaults to `.IOLoop.current`.
- Deprecated since Tornado 4.1.
:arg max_buffer_size: Maximum amount of incoming data to buffer;
defaults to 100MB.
:arg read_chunk_size: Amount of data to read at one time from the
.. versionchanged:: 4.0
Add the ``max_write_buffer_size`` parameter. Changed default
``read_chunk_size`` to 64KB.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been
+ removed.
"""
- self.io_loop = io_loop or ioloop.IOLoop.current()
+ self.io_loop = ioloop.IOLoop.current()
self.max_buffer_size = max_buffer_size or 104857600
# A chunk size that is too close to max_buffer_size can cause
# spurious failures.
self._close_callback = None
future = TracebackFuture()
- ssl_stream = SSLIOStream(socket, ssl_options=ssl_options,
- io_loop=self.io_loop)
+ ssl_stream = SSLIOStream(socket, ssl_options=ssl_options)
# Wrap the original close callback so we can fail our Future as well.
# If we had an "unwrap" counterpart to this method we would need
# to restore the original callback after our Future resolves
return sock
-def add_accept_handler(sock, callback, io_loop=None):
+def add_accept_handler(sock, callback):
"""Adds an `.IOLoop` event handler to accept new connections on ``sock``.
When a connection is accepted, ``callback(connection, address)`` will
is different from the ``callback(fd, events)`` signature used for
`.IOLoop` handlers.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- if io_loop is None:
- io_loop = IOLoop.current()
-
def accept_handler(fd, events):
# More connections may come in while we're handling callbacks;
# to prevent starvation of other tasks we must limit the number
continue
raise
callback(connection, address)
- io_loop.add_handler(sock, accept_handler, IOLoop.READ)
+ IOLoop.current().add_handler(sock, accept_handler, IOLoop.READ)
def is_valid_ip(ip):
``close_resolver=False``; use this if you want to reuse the same
executor elsewhere.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- def initialize(self, io_loop=None, executor=None, close_executor=True):
- self.io_loop = io_loop or IOLoop.current()
+ def initialize(self, executor=None, close_executor=True):
+ self.io_loop = IOLoop.current()
if executor is not None:
self.executor = executor
self.close_executor = close_executor
The `.IOLoop` will be blocked during the resolution, although the
callback will not be run until the next `.IOLoop` iteration.
"""
- def initialize(self, io_loop=None):
- super(BlockingResolver, self).initialize(io_loop=io_loop)
+ def initialize(self):
+ super(BlockingResolver, self).initialize()
class ThreadedResolver(ExecutorResolver):
_threadpool = None # type: ignore
_threadpool_pid = None # type: int
- def initialize(self, io_loop=None, num_threads=10):
+ def initialize(self, num_threads=10):
threadpool = ThreadedResolver._create_threadpool(num_threads)
super(ThreadedResolver, self).initialize(
- io_loop=io_loop, executor=threadpool, close_executor=False)
+ executor=threadpool, close_executor=False)
@classmethod
def _create_threadpool(cls, num_threads):
the default for ``tornado.simple_httpclient``, but other libraries
may default to ``AF_UNSPEC``.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- def initialize(self, io_loop=None):
- self.io_loop = io_loop or IOLoop.current()
+ def initialize(self):
+ self.io_loop = IOLoop.current()
self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb)
self.fds = {}
instead of ``reactor.run()``.
It is also possible to create a non-global reactor by calling
- ``tornado.platform.twisted.TornadoReactor(io_loop)``. However, if
+ ``tornado.platform.twisted.TornadoReactor()``. However, if
the `.IOLoop` and reactor are to be short-lived (such as those used in
unit tests), additional cleanup may be required. Specifically, it is
recommended to call::
before closing the `.IOLoop`.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- def __init__(self, io_loop=None):
- if not io_loop:
- io_loop = tornado.ioloop.IOLoop.current()
- self._io_loop = io_loop
+ def __init__(self):
+ self._io_loop = tornado.ioloop.IOLoop.current()
self._readers = {} # map of reader objects to fd
self._writers = {} # map of writer objects to fd
self._fds = {} # a map of fd to a (reader, writer) tuple
"""
def __init__(self):
# always use a new ioloop
- super(_TestReactor, self).__init__(IOLoop())
+ IOLoop(make_current=True)
+ super(_TestReactor, self).__init__()
+ IOLoop.clear_current()
def listenTCP(self, port, factory, backlog=50, interface=''):
# default to localhost to avoid firewall prompts on the mac
port, protocol, interface=interface, maxPacketSize=maxPacketSize)
-def install(io_loop=None):
+def install():
"""Install this package as the default Twisted reactor.
``install()`` must be called very early in the startup process,
in multi-process mode, and an external process manager such as
``supervisord`` is recommended instead.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- if not io_loop:
- io_loop = tornado.ioloop.IOLoop.current()
- reactor = TornadoReactor(io_loop)
+ reactor = TornadoReactor()
from twisted.internet.main import installReactor # type: ignore
installReactor(reactor)
return reactor
Requires Twisted 12.1 or newer.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- def initialize(self, io_loop=None):
- self.io_loop = io_loop or IOLoop.current()
+ def initialize(self):
# partial copy of twisted.names.client.createResolver, which doesn't
# allow for a reactor to be passed in.
- self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)
+ self.reactor = tornado.platform.twisted.TornadoReactor()
host_resolver = twisted.names.hosts.Resolver('/etc/hosts')
cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)
* ``stdin``, ``stdout``, and ``stderr`` may have the value
``tornado.process.Subprocess.STREAM``, which will make the corresponding
attribute of the resulting Subprocess a `.PipeIOStream`.
- * A new keyword argument ``io_loop`` may be used to pass in an IOLoop.
The ``Subprocess.STREAM`` option and the ``set_exit_callback`` and
``wait_for_exit`` methods do not work on Windows. There is
therefore no reason to use this class instead of
``subprocess.Popen`` on that platform.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
STREAM = object()
_waiting = {} # type: ignore
def __init__(self, *args, **kwargs):
- self.io_loop = kwargs.pop('io_loop', None) or ioloop.IOLoop.current()
+ self.io_loop = ioloop.IOLoop.current()
# All FDs we create should be closed on error; those in to_close
# should be closed in the parent process on success.
pipe_fds = []
kwargs['stdin'] = in_r
pipe_fds.extend((in_r, in_w))
to_close.append(in_r)
- self.stdin = PipeIOStream(in_w, io_loop=self.io_loop)
+ self.stdin = PipeIOStream(in_w)
if kwargs.get('stdout') is Subprocess.STREAM:
out_r, out_w = _pipe_cloexec()
kwargs['stdout'] = out_w
pipe_fds.extend((out_r, out_w))
to_close.append(out_w)
- self.stdout = PipeIOStream(out_r, io_loop=self.io_loop)
+ self.stdout = PipeIOStream(out_r)
if kwargs.get('stderr') is Subprocess.STREAM:
err_r, err_w = _pipe_cloexec()
kwargs['stderr'] = err_w
pipe_fds.extend((err_r, err_w))
to_close.append(err_w)
- self.stderr = PipeIOStream(err_r, io_loop=self.io_loop)
+ self.stderr = PipeIOStream(err_r)
try:
self.proc = subprocess.Popen(*args, **kwargs)
except:
signal handler is causing a problem.
"""
self._exit_callback = stack_context.wrap(callback)
- Subprocess.initialize(self.io_loop)
+ Subprocess.initialize()
Subprocess._waiting[self.pid] = self
Subprocess._try_cleanup_process(self.pid)
return future
@classmethod
- def initialize(cls, io_loop=None):
+ def initialize(cls):
"""Initializes the ``SIGCHLD`` handler.
The signal handler is run on an `.IOLoop` to avoid locking issues.
same one used by individual Subprocess objects (as long as the
``IOLoops`` are each running in separate threads).
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been
+ removed.
"""
if cls._initialized:
return
- if io_loop is None:
- io_loop = ioloop.IOLoop.current()
+ io_loop = ioloop.IOLoop.current()
cls._old_sigchld = signal.signal(
signal.SIGCHLD,
lambda sig, frame: io_loop.add_callback_from_signal(cls._cleanup))
from tornado.httpclient import HTTPResponse, HTTPError, AsyncHTTPClient, main, _RequestProxy
from tornado import httputil
from tornado.http1connection import HTTP1Connection, HTTP1ConnectionParameters
+from tornado.ioloop import IOLoop
from tornado.iostream import StreamClosedError
from tornado.netutil import Resolver, OverrideResolver, _client_ssl_defaults
from tornado.log import gen_log
are not reused, and callers cannot select the network interface to be
used.
"""
- def initialize(self, io_loop, max_clients=10,
+ def initialize(self, max_clients=10,
hostname_mapping=None, max_buffer_size=104857600,
resolver=None, defaults=None, max_header_size=None,
max_body_size=None):
.. versionchanged:: 4.2
Added the ``max_body_size`` argument.
"""
- super(SimpleAsyncHTTPClient, self).initialize(io_loop,
- defaults=defaults)
+ super(SimpleAsyncHTTPClient, self).initialize(defaults=defaults)
self.max_clients = max_clients
self.queue = collections.deque()
self.active = {}
self.resolver = resolver
self.own_resolver = False
else:
- self.resolver = Resolver(io_loop=io_loop)
+ self.resolver = Resolver()
self.own_resolver = True
if hostname_mapping is not None:
self.resolver = OverrideResolver(resolver=self.resolver,
mapping=hostname_mapping)
- self.tcp_client = TCPClient(resolver=self.resolver, io_loop=io_loop)
+ self.tcp_client = TCPClient(resolver=self.resolver)
def close(self):
super(SimpleAsyncHTTPClient, self).close()
def _handle_request(self, request, release_callback, final_callback):
self._connection_class()(
- self.io_loop, self, request, release_callback,
+ self, request, release_callback,
final_callback, self.max_buffer_size, self.tcp_client,
self.max_header_size, self.max_body_size)
class _HTTPConnection(httputil.HTTPMessageDelegate):
_SUPPORTED_METHODS = set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
- def __init__(self, io_loop, client, request, release_callback,
+ def __init__(self, client, request, release_callback,
final_callback, max_buffer_size, tcp_client,
max_header_size, max_body_size):
- self.start_time = io_loop.time()
- self.io_loop = io_loop
+ self.io_loop = IOLoop.current()
+ self.start_time = self.io_loop.time()
self.client = client
self.request = request
self.release_callback = release_callback
http://tools.ietf.org/html/rfc6555
"""
- def __init__(self, addrinfo, io_loop, connect):
- self.io_loop = io_loop
+ def __init__(self, addrinfo, connect):
+ self.io_loop = IOLoop.current()
self.connect = connect
self.future = Future()
class TCPClient(object):
"""A non-blocking TCP connection factory.
- .. versionchanged:: 4.1
- The ``io_loop`` argument is deprecated.
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- def __init__(self, resolver=None, io_loop=None):
- self.io_loop = io_loop or IOLoop.current()
+ def __init__(self, resolver=None):
if resolver is not None:
self.resolver = resolver
self._own_resolver = False
else:
- self.resolver = Resolver(io_loop=io_loop)
+ self.resolver = Resolver()
self._own_resolver = True
def close(self):
"""
addrinfo = yield self.resolver.resolve(host, port, af)
connector = _Connector(
- addrinfo, self.io_loop,
+ addrinfo,
functools.partial(self._create_stream, max_buffer_size,
source_ip=source_ip, source_port=source_port)
)
raise
try:
stream = IOStream(socket_obj,
- io_loop=self.io_loop,
max_buffer_size=max_buffer_size)
except socket.error as e:
fu = Future()
.. versionadded:: 3.1
The ``max_buffer_size`` argument.
+
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument has been removed.
"""
- def __init__(self, io_loop=None, ssl_options=None, max_buffer_size=None,
+ def __init__(self, ssl_options=None, max_buffer_size=None,
read_chunk_size=None):
- self.io_loop = io_loop
+ self.io_loop = IOLoop.current()
self.ssl_options = ssl_options
self._sockets = {} # fd -> socket object
self._pending_sockets = []
method and `tornado.process.fork_processes` to provide greater
control over the initialization of a multi-process server.
"""
- if self.io_loop is None:
- self.io_loop = IOLoop.current()
-
for sock in sockets:
self._sockets[sock.fileno()] = sock
- add_accept_handler(sock, self._handle_connection,
- io_loop=self.io_loop)
+ add_accept_handler(sock, self._handle_connection)
def add_socket(self, socket):
"""Singular version of `add_sockets`. Takes a single socket object."""
raise
try:
if self.ssl_options is not None:
- stream = SSLIOStream(connection, io_loop=self.io_loop,
+ stream = SSLIOStream(connection,
max_buffer_size=self.max_buffer_size,
read_chunk_size=self.read_chunk_size)
else:
- stream = IOStream(connection, io_loop=self.io_loop,
+ stream = IOStream(connection,
max_buffer_size=self.max_buffer_size,
read_chunk_size=self.read_chunk_size)
from tornado.concurrent import Future, return_future, ReturnValueIgnoredError, run_on_executor
from tornado.escape import utf8, to_unicode
from tornado import gen
+from tornado.ioloop import IOLoop
from tornado.iostream import IOStream
from tornado.log import app_log
from tornado import stack_context
class BaseCapClient(object):
- def __init__(self, port, io_loop):
+ def __init__(self, port):
self.port = port
- self.io_loop = io_loop
def process_response(self, data):
status, message = re.match('(.*)\t(.*)\n', to_unicode(data)).groups()
def capitalize(self, request_data, callback=None):
logging.info("capitalize")
self.request_data = request_data
- self.stream = IOStream(socket.socket(), io_loop=self.io_loop)
+ self.stream = IOStream(socket.socket())
self.stream.connect(('127.0.0.1', self.port),
callback=self.handle_connect)
self.future = Future()
def capitalize(self, request_data, callback):
logging.info("capitalize")
self.request_data = request_data
- self.stream = IOStream(socket.socket(), io_loop=self.io_loop)
+ self.stream = IOStream(socket.socket())
self.stream.connect(('127.0.0.1', self.port),
callback=self.handle_connect)
self.callback = callback
@gen.engine
def capitalize(self, request_data, callback):
logging.info('capitalize')
- stream = IOStream(socket.socket(), io_loop=self.io_loop)
+ stream = IOStream(socket.socket())
logging.info('connecting')
yield gen.Task(stream.connect, ('127.0.0.1', self.port))
stream.write(utf8(request_data + '\n'))
class ClientTestMixin(object):
def setUp(self):
super(ClientTestMixin, self).setUp() # type: ignore
- self.server = CapServer(io_loop=self.io_loop)
+ self.server = CapServer()
sock, port = bind_unused_port()
self.server.add_sockets([sock])
- self.client = self.client_class(io_loop=self.io_loop, port=port)
+ self.client = self.client_class(port=port)
def tearDown(self):
self.server.stop()
@unittest.skipIf(pycurl is None, "pycurl module not present")
class CurlHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase):
def get_http_client(self):
- client = CurlAsyncHTTPClient(io_loop=self.io_loop,
- defaults=dict(allow_ipv6=False))
+ client = CurlAsyncHTTPClient(defaults=dict(allow_ipv6=False))
# make sure AsyncHTTPClient magic doesn't give us the wrong class
self.assertTrue(isinstance(client, CurlAsyncHTTPClient))
return client
])
def create_client(self, **kwargs):
- return CurlAsyncHTTPClient(self.io_loop, force_instance=True,
+ return CurlAsyncHTTPClient(force_instance=True,
defaults=dict(allow_ipv6=False),
**kwargs)
@asynchronous
@gen.engine
def get(self):
- io_loop = self.request.connection.stream.io_loop
- client = AsyncHTTPClient(io_loop=io_loop)
+ client = AsyncHTTPClient()
response = yield gen.Task(client.fetch, self.get_argument('url'))
response.rethrow()
self.finish(b"got response: " + response.body)
self.io_loop.add_timeout(datetime.timedelta(seconds=0.1),
lambda: future.set_result('asdf'))
result = yield gen.with_timeout(datetime.timedelta(seconds=3600),
- future, io_loop=self.io_loop)
+ future)
self.assertEqual(result, 'asdf')
@gen_test
lambda: future.set_exception(ZeroDivisionError()))
with self.assertRaises(ZeroDivisionError):
yield gen.with_timeout(datetime.timedelta(seconds=3600),
- future, io_loop=self.io_loop)
+ future)
@gen_test
def test_already_resolved(self):
future = Future()
future.set_result('asdf')
result = yield gen.with_timeout(datetime.timedelta(seconds=3600),
- future, io_loop=self.io_loop)
+ future)
self.assertEqual(result, 'asdf')
@unittest.skipIf(futures is None, 'futures module not present')
def accept_callback(conn, address):
# fake an HTTP server using chunked encoding where the final chunks
# and connection close all happen at once
- stream = IOStream(conn, io_loop=self.io_loop)
+ stream = IOStream(conn)
stream.read_until(b"\r\n\r\n",
functools.partial(write_response, stream))
- netutil.add_accept_handler(sock, accept_callback, self.io_loop)
+ netutil.add_accept_handler(sock, accept_callback)
self.http_client.fetch("http://127.0.0.1:%d/" % port, self.stop)
resp = self.wait()
resp.rethrow()
def test_configure_defaults(self):
defaults = dict(user_agent='TestDefaultUserAgent', allow_ipv6=False)
# Construct a new instance of the configured client class
- client = self.http_client.__class__(self.io_loop, force_instance=True,
+ client = self.http_client.__class__(force_instance=True,
defaults=defaults)
try:
client.fetch(self.get_url('/user_agent'), callback=self.stop)
""".replace(b"\n", b"\r\n"), callback=stream.close)
def accept_callback(conn, address):
- stream = IOStream(conn, io_loop=self.io_loop)
+ stream = IOStream(conn)
stream.read_until(b"\r\n\r\n",
functools.partial(write_response, stream))
- netutil.add_accept_handler(sock, accept_callback, self.io_loop)
+ netutil.add_accept_handler(sock, accept_callback)
self.http_client.fetch("http://127.0.0.1:%d/" % port, self.stop)
resp = self.wait()
resp.rethrow()
'AsyncIOMainLoop')
self.server_ioloop = IOLoop()
- sock, self.port = bind_unused_port()
- app = Application([('/', HelloWorldHandler)])
- self.server = HTTPServer(app, io_loop=self.server_ioloop)
- self.server.add_socket(sock)
+ @gen.coroutine
+ def init_server():
+ sock, self.port = bind_unused_port()
+ app = Application([('/', HelloWorldHandler)])
+ self.server = HTTPServer(app)
+ self.server.add_socket(sock)
+ self.server_ioloop.run_sync(init_server)
self.server_thread = threading.Thread(target=self.server_ioloop.start)
self.server_thread.start()
# Run through a 100-continue interaction by hand:
# When given Expect: 100-continue, we get a 100 response after the
# headers, and then the real response after the body.
- stream = IOStream(socket.socket(), io_loop=self.io_loop)
+ stream = IOStream(socket.socket())
stream.connect(("127.0.0.1", self.get_http_port()), callback=self.stop)
self.wait()
stream.write(b"\r\n".join([b"POST /hello HTTP/1.1",
self.sockfile = os.path.join(self.tmpdir, "test.sock")
sock = netutil.bind_unix_socket(self.sockfile)
app = Application([("/hello", HelloWorldRequestHandler)])
- self.server = HTTPServer(app, io_loop=self.io_loop)
+ self.server = HTTPServer(app)
self.server.add_socket(sock)
- self.stream = IOStream(socket.socket(socket.AF_UNIX), io_loop=self.io_loop)
+ self.stream = IOStream(socket.socket(socket.AF_UNIX))
self.stream.connect(self.sockfile, self.stop)
self.wait()
# The next few methods are a crude manual http client
def connect(self):
- self.stream = IOStream(socket.socket(), io_loop=self.io_loop)
+ self.stream = IOStream(socket.socket())
self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)
self.wait()
def get_http_client(self):
# body_producer doesn't work on curl_httpclient, so override the
# configured AsyncHTTPClient implementation.
- return SimpleAsyncHTTPClient(io_loop=self.io_loop)
+ return SimpleAsyncHTTPClient()
def get_httpserver_options(self):
return dict(chunk_size=self.CHUNK_SIZE, decompress_request=True)
def get_http_client(self):
# body_producer doesn't work on curl_httpclient, so override the
# configured AsyncHTTPClient implementation.
- return SimpleAsyncHTTPClient(io_loop=self.io_loop)
+ return SimpleAsyncHTTPClient()
def test_small_body(self):
response = self.fetch('/buffered', method='PUT', body=b'a' * 4096)
def connect_callback():
streams[1] = client_stream
self.stop()
- netutil.add_accept_handler(listener, accept_callback,
- io_loop=self.io_loop)
+ netutil.add_accept_handler(listener, accept_callback)
client_stream = self._make_client_iostream(socket.socket(), **kwargs)
client_stream.connect(('127.0.0.1', port),
callback=connect_callback)
# epoll IOLoop in this respect)
cleanup_func, port = refusing_port()
self.addCleanup(cleanup_func)
- stream = IOStream(socket.socket(), self.io_loop)
+ stream = IOStream(socket.socket())
self.connect_called = False
def connect_callback():
# so we mock it instead. If IOStream changes to call a Resolver
# before sock.connect, the mock target will need to change too.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
- stream = IOStream(s, io_loop=self.io_loop)
+ stream = IOStream(s)
stream.set_close_callback(self.stop)
with mock.patch('socket.socket.connect',
side_effect=socket.gaierror(errno.EIO, 'boom')):
class TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):
def _make_client_iostream(self):
- return IOStream(socket.socket(), io_loop=self.io_loop)
+ return IOStream(socket.socket())
class TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):
def _make_client_iostream(self):
- return SSLIOStream(socket.socket(), io_loop=self.io_loop,
+ return SSLIOStream(socket.socket(),
ssl_options=dict(cert_reqs=ssl.CERT_NONE))
server_side=True,
do_handshake_on_connect=False,
**_server_ssl_options())
- return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)
+ return SSLIOStream(connection, **kwargs)
def _make_client_iostream(self, connection, **kwargs):
- return SSLIOStream(connection, io_loop=self.io_loop,
+ return SSLIOStream(connection,
ssl_options=dict(cert_reqs=ssl.CERT_NONE),
**kwargs)
connection = ssl_wrap_socket(connection, context,
server_side=True,
do_handshake_on_connect=False)
- return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)
+ return SSLIOStream(connection, **kwargs)
def _make_client_iostream(self, connection, **kwargs):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- return SSLIOStream(connection, io_loop=self.io_loop,
- ssl_options=context, **kwargs)
+ return SSLIOStream(connection, ssl_options=context, **kwargs)
class TestIOStreamStartTLS(AsyncTestCase):
def test_pipe_iostream(self):
r, w = os.pipe()
- rs = PipeIOStream(r, io_loop=self.io_loop)
- ws = PipeIOStream(w, io_loop=self.io_loop)
+ rs = PipeIOStream(r)
+ ws = PipeIOStream(w)
ws.write(b"hel")
ws.write(b"lo world")
def test_pipe_iostream_big_write(self):
r, w = os.pipe()
- rs = PipeIOStream(r, io_loop=self.io_loop)
- ws = PipeIOStream(w, io_loop=self.io_loop)
+ rs = PipeIOStream(r)
+ ws = PipeIOStream(w)
NUM_BYTES = 1048576
class BlockingResolverTest(AsyncTestCase, _ResolverTestMixin):
def setUp(self):
super(BlockingResolverTest, self).setUp()
- self.resolver = BlockingResolver(io_loop=self.io_loop)
+ self.resolver = BlockingResolver()
# getaddrinfo-based tests need mocking to reliably generate errors;
class BlockingResolverErrorTest(AsyncTestCase, _ResolverErrorTestMixin):
def setUp(self):
super(BlockingResolverErrorTest, self).setUp()
- self.resolver = BlockingResolver(io_loop=self.io_loop)
+ self.resolver = BlockingResolver()
self.real_getaddrinfo = socket.getaddrinfo
socket.getaddrinfo = _failing_getaddrinfo
class ThreadedResolverTest(AsyncTestCase, _ResolverTestMixin):
def setUp(self):
super(ThreadedResolverTest, self).setUp()
- self.resolver = ThreadedResolver(io_loop=self.io_loop)
+ self.resolver = ThreadedResolver()
def tearDown(self):
self.resolver.close()
class ThreadedResolverErrorTest(AsyncTestCase, _ResolverErrorTestMixin):
def setUp(self):
super(ThreadedResolverErrorTest, self).setUp()
- self.resolver = BlockingResolver(io_loop=self.io_loop)
+ self.resolver = BlockingResolver()
self.real_getaddrinfo = socket.getaddrinfo
socket.getaddrinfo = _failing_getaddrinfo
class CaresResolverTest(AsyncTestCase, _ResolverTestMixin):
def setUp(self):
super(CaresResolverTest, self).setUp()
- self.resolver = CaresResolver(io_loop=self.io_loop)
+ self.resolver = CaresResolver()
# TwistedResolver produces consistent errors in our test cases so we
_ResolverErrorTestMixin):
def setUp(self):
super(TwistedResolverTest, self).setUp()
- self.resolver = TwistedResolver(io_loop=self.io_loop)
+ self.resolver = TwistedResolver()
class IsValidIPTest(unittest.TestCase):
"LayeredTwistedIOLoop")
subproc = Subprocess([sys.executable, '-u', '-i'],
stdin=Subprocess.STREAM,
- stdout=Subprocess.STREAM, stderr=subprocess.STDOUT,
- io_loop=self.io_loop)
+ stdout=Subprocess.STREAM, stderr=subprocess.STDOUT)
self.addCleanup(lambda: (subproc.proc.terminate(), subproc.proc.wait()))
subproc.stdout.read_until(b'>>> ', self.stop)
self.wait()
# Close the parent's stdin handle and see that the child recognizes it.
subproc = Subprocess([sys.executable, '-u', '-i'],
stdin=Subprocess.STREAM,
- stdout=Subprocess.STREAM, stderr=subprocess.STDOUT,
- io_loop=self.io_loop)
+ stdout=Subprocess.STREAM, stderr=subprocess.STDOUT)
self.addCleanup(lambda: (subproc.proc.terminate(), subproc.proc.wait()))
subproc.stdout.read_until(b'>>> ', self.stop)
self.wait()
skip_if_twisted()
subproc = Subprocess([sys.executable, '-u', '-c',
r"import sys; sys.stderr.write('hello\n')"],
- stderr=Subprocess.STREAM,
- io_loop=self.io_loop)
+ stderr=Subprocess.STREAM)
self.addCleanup(lambda: (subproc.proc.terminate(), subproc.proc.wait()))
subproc.stderr.read_until(b'\n', self.stop)
data = self.wait()
def test_sigchild(self):
# Twisted's SIGCHLD handler and Subprocess's conflict with each other.
skip_if_twisted()
- Subprocess.initialize(io_loop=self.io_loop)
+ Subprocess.initialize()
self.addCleanup(Subprocess.uninitialize)
- subproc = Subprocess([sys.executable, '-c', 'pass'],
- io_loop=self.io_loop)
+ subproc = Subprocess([sys.executable, '-c', 'pass'])
subproc.set_exit_callback(self.stop)
ret = self.wait()
self.assertEqual(ret, 0)
def test_sigchild_signal(self):
skip_if_twisted()
- Subprocess.initialize(io_loop=self.io_loop)
+ Subprocess.initialize()
self.addCleanup(Subprocess.uninitialize)
subproc = Subprocess([sys.executable, '-c',
'import time; time.sleep(30)'],
- stdout=Subprocess.STREAM,
- io_loop=self.io_loop)
+ stdout=Subprocess.STREAM)
subproc.set_exit_callback(self.stop)
os.kill(subproc.pid, signal.SIGTERM)
try:
class SimpleHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase):
def get_http_client(self):
- client = SimpleAsyncHTTPClient(io_loop=self.io_loop,
- force_instance=True)
+ client = SimpleAsyncHTTPClient(force_instance=True)
self.assertTrue(isinstance(client, SimpleAsyncHTTPClient))
return client
def test_singleton(self):
# Class "constructor" reuses objects on the same IOLoop
- self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is
- SimpleAsyncHTTPClient(self.io_loop))
+ self.assertTrue(SimpleAsyncHTTPClient() is
+ SimpleAsyncHTTPClient())
# unless force_instance is used
- self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not
- SimpleAsyncHTTPClient(self.io_loop,
- force_instance=True))
+ self.assertTrue(SimpleAsyncHTTPClient() is not
+ SimpleAsyncHTTPClient(force_instance=True))
# different IOLoops use different objects
with closing(IOLoop()) as io_loop2:
- self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not
- SimpleAsyncHTTPClient(io_loop2))
+ client1 = self.io_loop.run_sync(gen.coroutine(SimpleAsyncHTTPClient))
+ client2 = io_loop2.run_sync(gen.coroutine(SimpleAsyncHTTPClient))
+ self.assertTrue(client1 is not client2)
def test_connection_limit(self):
with closing(self.create_client(max_clients=2)) as client:
self.http_client = self.create_client()
def create_client(self, **kwargs):
- return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,
- **kwargs)
+ return SimpleAsyncHTTPClient(force_instance=True, **kwargs)
class SimpleHTTPSClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPSTestCase):
self.http_client = self.create_client()
def create_client(self, **kwargs):
- return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,
+ return SimpleAsyncHTTPClient(force_instance=True,
defaults=dict(validate_cert=False),
**kwargs)
def test_max_clients(self):
AsyncHTTPClient.configure(SimpleAsyncHTTPClient)
- with closing(AsyncHTTPClient(
- self.io_loop, force_instance=True)) as client:
+ with closing(AsyncHTTPClient(force_instance=True)) as client:
self.assertEqual(client.max_clients, 10)
with closing(AsyncHTTPClient(
- self.io_loop, max_clients=11, force_instance=True)) as client:
+ max_clients=11, force_instance=True)) as client:
self.assertEqual(client.max_clients, 11)
# Now configure max_clients statically and try overriding it
# with each way max_clients can be passed
AsyncHTTPClient.configure(SimpleAsyncHTTPClient, max_clients=12)
- with closing(AsyncHTTPClient(
- self.io_loop, force_instance=True)) as client:
+ with closing(AsyncHTTPClient(force_instance=True)) as client:
self.assertEqual(client.max_clients, 12)
with closing(AsyncHTTPClient(
- self.io_loop, max_clients=13, force_instance=True)) as client:
+ max_clients=13, force_instance=True)) as client:
self.assertEqual(client.max_clients, 13)
with closing(AsyncHTTPClient(
- self.io_loop, max_clients=14, force_instance=True)) as client:
+ max_clients=14, force_instance=True)) as client:
self.assertEqual(client.max_clients, 14)
def setUp(self):
super(HostnameMappingTestCase, self).setUp()
self.http_client = SimpleAsyncHTTPClient(
- self.io_loop,
hostname_mapping={
'www.example.com': '127.0.0.1',
('foo.example.com', 8000): ('127.0.0.1', self.get_http_port()),
super(ResolveTimeoutTestCase, self).setUp()
self.http_client = SimpleAsyncHTTPClient(
- self.io_loop,
resolver=BadResolver())
def get_app(self):
('/large', LargeHeaders)])
def get_http_client(self):
- return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_header_size=1024)
+ return SimpleAsyncHTTPClient(max_header_size=1024)
def test_small_headers(self):
response = self.fetch('/small')
('/large', LargeBody)])
def get_http_client(self):
- return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 64)
+ return SimpleAsyncHTTPClient(max_body_size=1024 * 64)
def test_small_body(self):
response = self.fetch('/small')
def get_http_client(self):
# 100KB body with 64KB buffer
- return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 100, max_buffer_size=1024 * 64)
+ return SimpleAsyncHTTPClient(max_body_size=1024 * 100, max_buffer_size=1024 * 64)
def test_large_body(self):
response = self.fetch('/large')
from __future__ import absolute_import, division, print_function
from tornado import gen
+from tornado.ioloop import IOLoop
from tornado.log import app_log
from tornado.stack_context import (StackContext, wrap, NullContext, StackContextInconsistentError,
ExceptionStackContext, run_with_stack_context, _state)
class TestRequestHandler(RequestHandler):
- def __init__(self, app, request, io_loop):
+ def __init__(self, app, request):
super(TestRequestHandler, self).__init__(app, request)
- self.io_loop = io_loop
@asynchronous
def get(self):
logging.debug('in get()')
# call self.part2 without a self.async_callback wrapper. Its
# exception should still get thrown
- self.io_loop.add_callback(self.part2)
+ IOLoop.current().add_callback(self.part2)
def part2(self):
logging.debug('in part2()')
# Go through a third layer to make sure that contexts once restored
# are again passed on to future callbacks
- self.io_loop.add_callback(self.part3)
+ IOLoop.current().add_callback(self.part3)
def part3(self):
logging.debug('in part3()')
class HTTPStackContextTest(AsyncHTTPTestCase):
def get_app(self):
- return Application([('/', TestRequestHandler,
- dict(io_loop=self.io_loop))])
+ return Application([('/', TestRequestHandler)])
def test_stack_context(self):
with ExpectLog(app_log, "Uncaught exception GET /"):
future.set_exception(IOError())
def start_connect(self, addrinfo):
- conn = _Connector(addrinfo, self.io_loop, self.create_stream)
+ conn = _Connector(addrinfo, self.create_stream)
# Give it a huge timeout; we'll trigger timeouts manually.
future = conn.start(3600)
return conn, future
class ReactorTestCase(unittest.TestCase):
def setUp(self):
self._saved_signals = save_signal_handlers()
- self._io_loop = IOLoop()
- self._reactor = TornadoReactor(self._io_loop)
+ self._io_loop = IOLoop(make_current=True)
+ self._reactor = TornadoReactor()
+ IOLoop.clear_current()
def tearDown(self):
self._io_loop.close(all_fds=True)
self.saved_signals = save_signal_handlers()
self.io_loop = IOLoop()
self.io_loop.make_current()
- self.reactor = TornadoReactor(self.io_loop)
+ self.reactor = TornadoReactor()
def tearDown(self):
self.reactor.disconnectAll()
self.write("Hello from tornado!")
app = Application([('/', HelloHandler)],
log_function=lambda x: None)
- server = HTTPServer(app, io_loop=self.io_loop)
+ server = HTTPServer(app)
sock, self.tornado_port = bind_unused_port()
server.add_sockets([sock])
def tornado_fetch(self, url, runner):
responses = []
- client = AsyncHTTPClient(self.io_loop)
+ client = AsyncHTTPClient()
def callback(response):
responses.append(response)
# get the next-best IOLoop implementation, so use the lowest common
# denominator.
self.real_io_loop = SelectIOLoop(make_current=False) # type: ignore
- reactor = TornadoReactor(io_loop=self.real_io_loop)
+ reactor = self.real_io_loop.run_sync(gen.coroutine(TornadoReactor))
super(LayeredTwistedIOLoop, self).initialize(reactor=reactor, **kwargs)
self.add_callback(self.make_current)
def test_connection_close(self):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.connect(("127.0.0.1", self.get_http_port()))
- self.stream = IOStream(s, io_loop=self.io_loop)
+ self.stream = IOStream(s)
self.stream.write(b"GET / HTTP/1.0\r\n\r\n")
self.wait()
def get_http_client(self):
# simple_httpclient only: curl doesn't expose the reason string
- return SimpleAsyncHTTPClient(io_loop=self.io_loop)
+ return SimpleAsyncHTTPClient()
def test_status(self):
response = self.fetch("/?code=304")
def get_http_client(self):
# simple_httpclient only: curl doesn't expose the reason string
- return SimpleAsyncHTTPClient(io_loop=self.io_loop)
+ return SimpleAsyncHTTPClient()
def test_raise_with_reason(self):
response = self.fetch("/")
# Use a raw connection so we can control the sending of data.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.connect(("127.0.0.1", self.get_http_port()))
- stream = IOStream(s, io_loop=self.io_loop)
+ stream = IOStream(s)
stream.write(b"GET " + url + b" HTTP/1.1\r\n")
if connection_close:
stream.write(b"Connection: close\r\n")
def get_http_client(self):
# simple_httpclient only: curl doesn't support body_producer.
- return SimpleAsyncHTTPClient(io_loop=self.io_loop)
+ return SimpleAsyncHTTPClient()
# Test all the slightly different code paths for fixed, chunked, etc bodies.
def test_flow_control_fixed_body(self):
def test_websocket_callbacks(self):
websocket_connect(
'ws://127.0.0.1:%d/echo' % self.get_http_port(),
- io_loop=self.io_loop, callback=self.stop)
+ callback=self.stop)
ws = self.wait().result()
ws.write_message('hello')
ws.read_message(self.stop)
with ExpectLog(gen_log, ".*"):
yield websocket_connect(
'ws://127.0.0.1:%d/' % port,
- io_loop=self.io_loop,
connect_timeout=3600)
@gen_test
url = 'ws://127.0.0.1:%d/echo' % port
headers = {'Origin': 'http://127.0.0.1:%d' % port}
- ws = yield websocket_connect(HTTPRequest(url, headers=headers),
- io_loop=self.io_loop)
+ ws = yield websocket_connect(HTTPRequest(url, headers=headers))
ws.write_message('hello')
response = yield ws.read_message()
self.assertEqual(response, 'hello')
url = 'ws://127.0.0.1:%d/echo' % port
headers = {'Origin': 'http://127.0.0.1:%d/something' % port}
- ws = yield websocket_connect(HTTPRequest(url, headers=headers),
- io_loop=self.io_loop)
+ ws = yield websocket_connect(HTTPRequest(url, headers=headers))
ws.write_message('hello')
response = yield ws.read_message()
self.assertEqual(response, 'hello')
headers = {'Origin': '127.0.0.1:%d' % port}
with self.assertRaises(HTTPError) as cm:
- yield websocket_connect(HTTPRequest(url, headers=headers),
- io_loop=self.io_loop)
+ yield websocket_connect(HTTPRequest(url, headers=headers))
self.assertEqual(cm.exception.code, 403)
@gen_test
headers = {'Origin': 'http://somewhereelse.com'}
with self.assertRaises(HTTPError) as cm:
- yield websocket_connect(HTTPRequest(url, headers=headers),
- io_loop=self.io_loop)
+ yield websocket_connect(HTTPRequest(url, headers=headers))
self.assertEqual(cm.exception.code, 403)
headers = {'Origin': 'http://subtenant.localhost'}
with self.assertRaises(HTTPError) as cm:
- yield websocket_connect(HTTPRequest(url, headers=headers),
- io_loop=self.io_loop)
+ yield websocket_connect(HTTPRequest(url, headers=headers))
self.assertEqual(cm.exception.code, 403)
callbacks should call ``self.stop()`` to signal completion.
By default, a new `.IOLoop` is constructed for each test and is available
- as ``self.io_loop``. This `.IOLoop` should be used in the construction of
- HTTP clients/servers, etc. If the code being tested requires a
+ as ``self.io_loop``. If the code being tested requires a
global `.IOLoop`, subclasses should override `get_new_ioloop` to return it.
The `.IOLoop`'s ``start`` and ``stop`` methods should not be
class MyTestCase(AsyncTestCase):
@tornado.testing.gen_test
def test_http_fetch(self):
- client = AsyncHTTPClient(self.io_loop)
+ client = AsyncHTTPClient()
response = yield client.fetch("http://www.tornadoweb.org")
# Test contents of response
self.assertIn("FriendFeed", response.body)
# This test uses argument passing between self.stop and self.wait.
class MyTestCase2(AsyncTestCase):
def test_http_fetch(self):
- client = AsyncHTTPClient(self.io_loop)
+ client = AsyncHTTPClient()
client.fetch("http://www.tornadoweb.org/", self.stop)
response = self.wait()
# Test contents of response
# This test uses an explicit callback-based style.
class MyTestCase3(AsyncTestCase):
def test_http_fetch(self):
- client = AsyncHTTPClient(self.io_loop)
+ client = AsyncHTTPClient()
client.fetch("http://www.tornadoweb.org/", self.handle_fetch)
self.wait()
self.http_server.add_sockets([sock])
def get_http_client(self):
- return AsyncHTTPClient(io_loop=self.io_loop)
+ return AsyncHTTPClient()
def get_http_server(self):
- return HTTPServer(self._app, io_loop=self.io_loop,
- **self.get_httpserver_options())
+ return HTTPServer(self._app, **self.get_httpserver_options())
def get_app(self):
"""Should be overridden by subclasses to return a
Interface is generally the same as `AsyncHTTPTestCase`.
"""
def get_http_client(self):
- return AsyncHTTPClient(io_loop=self.io_loop, force_instance=True,
+ return AsyncHTTPClient(force_instance=True,
defaults=dict(validate_cert=False))
def get_httpserver_options(self):
This class should not be instantiated directly; use the
`websocket_connect` function instead.
"""
- def __init__(self, io_loop, request, on_message_callback=None,
+ def __init__(self, request, on_message_callback=None,
compression_options=None, ping_interval=None, ping_timeout=None,
max_message_size=None):
self.compression_options = compression_options
request.headers['Sec-WebSocket-Extensions'] = (
'permessage-deflate; client_max_window_bits')
- self.tcp_client = TCPClient(io_loop=io_loop)
+ self.tcp_client = TCPClient()
super(WebSocketClientConnection, self).__init__(
- io_loop, None, request, lambda: None, self._on_http_response,
+ None, request, lambda: None, self._on_http_response,
104857600, self.tcp_client, 65536, 104857600)
def close(self, code=None, reason=None):
compression_options=self.compression_options)
-def websocket_connect(url, io_loop=None, callback=None, connect_timeout=None,
+def websocket_connect(url, callback=None, connect_timeout=None,
on_message_callback=None, compression_options=None,
ping_interval=None, ping_timeout=None,
max_message_size=None):
.. versionchanged:: 4.1
Added ``compression_options`` and ``on_message_callback``.
- The ``io_loop`` argument is deprecated.
.. versionchanged:: 4.5
Added the ``ping_interval``, ``ping_timeout``, and ``max_message_size``
arguments, which have the same meaning as in `WebSocketHandler`.
+
+ .. versionchanged:: 5.0
+ The ``io_loop`` argument (deprecated since version 4.1) has been removed.
"""
- if io_loop is None:
- io_loop = IOLoop.current()
if isinstance(url, httpclient.HTTPRequest):
assert connect_timeout is None
request = url
request = httpclient.HTTPRequest(url, connect_timeout=connect_timeout)
request = httpclient._RequestProxy(
request, httpclient.HTTPRequest._DEFAULTS)
- conn = WebSocketClientConnection(io_loop, request,
+ conn = WebSocketClientConnection(request,
on_message_callback=on_message_callback,
compression_options=compression_options,
ping_interval=ping_interval,
ping_timeout=ping_timeout,
max_message_size=max_message_size)
if callback is not None:
- io_loop.add_future(conn.connect_future, callback)
+ IOLoop.current().add_future(conn.connect_future, callback)
return conn.connect_future