async def wait_for_http_server(url, timeout=10, ssl_context=None): """Wait for an HTTP Server to respond at url. Any non-5XX response code will do, even 404. """ loop = ioloop.IOLoop.current() tic = loop.time() client = AsyncHTTPClient() if ssl_context: client.ssl_options = ssl_context async def is_reachable(): try: r = await client.fetch(url, follow_redirects=False) return r except HTTPError as e: if e.code >= 500: # failed to respond properly, wait and try again if e.code != 599: # we expect 599 for no connection, # but 502 or other proxy error is conceivable app_log.warning( "Server at %s responded with error: %s", url, e.code) else: app_log.debug("Server at %s responded with %s", url, e.code) return e.response except (OSError, socket.error) as e: if e.errno not in {errno.ECONNABORTED, errno.ECONNREFUSED, errno.ECONNRESET}: app_log.warning("Failed to connect to %s (%s)", url, e) return False re = await exponential_backoff( is_reachable, "Server at {url} didn't respond in {timeout} seconds".format(url=url, timeout=timeout), timeout=timeout ) return re