{
    "file_diffs": [
        {
            "old_file_content": "",
            "new_file_content": "Updated ClientSession's auth logic to include default auth only if the request URL's origin matches _base_url; otherwise, the auth will not be included -- by :user:`MaximZemskov`\n",
            "header": {
                "file": {
                    "path": "CHANGES/8966.feature.rst"
                },
                "misc_line": "new file mode 100644"
            },
            "index_line": {
                "old_commit_hash": "00000000",
                "new_commit_hash": "ab1dc45b",
                "mode": ""
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "/dev/null"
            },
            "plus_file": {
                "path": "b/CHANGES/8966.feature.rst"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 0,
                            "length": 0
                        },
                        "new_range": {
                            "start": 1,
                            "length": null
                        },
                        "section": ""
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "Updated ClientSession's auth logic to include default auth only if the request URL's origin matches _base_url; otherwise, the auth will not be included -- by :user:`MaximZemskov`",
                                "type": "added"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "\"\"\"HTTP Client for asyncio.\"\"\"\n\nimport asyncio\nimport base64\nimport dataclasses\nimport hashlib\nimport json\nimport os\nimport sys\nimport traceback\nimport warnings\nfrom contextlib import suppress\nfrom types import TracebackType\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Awaitable,\n    Callable,\n    Collection,\n    Coroutine,\n    Final,\n    FrozenSet,\n    Generator,\n    Generic,\n    Iterable,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n    TypedDict,\n    TypeVar,\n    Union,\n    final,\n)\n\nfrom multidict import CIMultiDict, MultiDict, MultiDictProxy, istr\nfrom yarl import URL\n\nfrom . import hdrs, http, payload\nfrom .abc import AbstractCookieJar\nfrom .client_exceptions import (\n    ClientConnectionError,\n    ClientConnectorCertificateError,\n    ClientConnectorError,\n    ClientConnectorSSLError,\n    ClientError,\n    ClientHttpProxyError,\n    ClientOSError,\n    ClientPayloadError,\n    ClientProxyConnectionError,\n    ClientResponseError,\n    ClientSSLError,\n    ConnectionTimeoutError,\n    ContentTypeError,\n    InvalidURL,\n    InvalidUrlClientError,\n    InvalidUrlRedirectClientError,\n    NonHttpUrlClientError,\n    NonHttpUrlRedirectClientError,\n    RedirectClientError,\n    ServerConnectionError,\n    ServerDisconnectedError,\n    ServerFingerprintMismatch,\n    ServerTimeoutError,\n    SocketTimeoutError,\n    TooManyRedirects,\n    WSServerHandshakeError,\n)\nfrom .client_reqrep import (\n    SSL_ALLOWED_TYPES,\n    ClientRequest,\n    ClientResponse,\n    Fingerprint,\n    RequestInfo,\n)\nfrom .client_ws import (\n    DEFAULT_WS_CLIENT_TIMEOUT,\n    ClientWebSocketResponse,\n    ClientWSTimeout,\n)\nfrom .connector import (\n    HTTP_AND_EMPTY_SCHEMA_SET,\n    BaseConnector,\n    NamedPipeConnector,\n    TCPConnector,\n    UnixConnector,\n)\nfrom .cookiejar import CookieJar\nfrom .helpers import (\n    _SENTINEL,\n    BasicAuth,\n    TimeoutHandle,\n    ceil_timeout,\n    get_env_proxy_for_url,\n    method_must_be_empty_body,\n    sentinel,\n    strip_auth_from_url,\n)\nfrom .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter\nfrom .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse\nfrom .streams import FlowControlDataQueue\nfrom .tracing import Trace, TraceConfig\nfrom .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL\n\n__all__ = (\n    # client_exceptions\n    \"ClientConnectionError\",\n    \"ClientConnectorCertificateError\",\n    \"ClientConnectorError\",\n    \"ClientConnectorSSLError\",\n    \"ClientError\",\n    \"ClientHttpProxyError\",\n    \"ClientOSError\",\n    \"ClientPayloadError\",\n    \"ClientProxyConnectionError\",\n    \"ClientResponseError\",\n    \"ClientSSLError\",\n    \"ConnectionTimeoutError\",\n    \"ContentTypeError\",\n    \"InvalidURL\",\n    \"InvalidUrlClientError\",\n    \"RedirectClientError\",\n    \"NonHttpUrlClientError\",\n    \"InvalidUrlRedirectClientError\",\n    \"NonHttpUrlRedirectClientError\",\n    \"ServerConnectionError\",\n    \"ServerDisconnectedError\",\n    \"ServerFingerprintMismatch\",\n    \"ServerTimeoutError\",\n    \"SocketTimeoutError\",\n    \"TooManyRedirects\",\n    \"WSServerHandshakeError\",\n    # client_reqrep\n    \"ClientRequest\",\n    \"ClientResponse\",\n    \"Fingerprint\",\n    \"RequestInfo\",\n    # connector\n    \"BaseConnector\",\n    \"TCPConnector\",\n    \"UnixConnector\",\n    \"NamedPipeConnector\",\n    # client_ws\n    \"ClientWebSocketResponse\",\n    # client\n    \"ClientSession\",\n    \"ClientTimeout\",\n    \"ClientWSTimeout\",\n    \"request\",\n)\n\n\nif TYPE_CHECKING:\n    from ssl import SSLContext\nelse:\n    SSLContext = None\n\nif sys.version_info >= (3, 11) and TYPE_CHECKING:\n    from typing import Unpack\n\n\nclass _RequestOptions(TypedDict, total=False):\n    params: Union[Mapping[str, Union[str, int]], str, None]\n    data: Any\n    json: Any\n    cookies: Union[LooseCookies, None]\n    headers: Union[LooseHeaders, None]\n    skip_auto_headers: Union[Iterable[str], None]\n    auth: Union[BasicAuth, None]\n    allow_redirects: bool\n    max_redirects: int\n    compress: Union[str, None]\n    chunked: Union[bool, None]\n    expect100: bool\n    raise_for_status: Union[None, bool, Callable[[ClientResponse], Awaitable[None]]]\n    read_until_eof: bool\n    proxy: Union[StrOrURL, None]\n    proxy_auth: Union[BasicAuth, None]\n    timeout: \"Union[ClientTimeout, _SENTINEL, None]\"\n    ssl: Union[SSLContext, bool, Fingerprint]\n    server_hostname: Union[str, None]\n    proxy_headers: Union[LooseHeaders, None]\n    trace_request_ctx: Union[Mapping[str, str], None]\n    read_bufsize: Union[int, None]\n    auto_decompress: Union[bool, None]\n    max_line_size: Union[int, None]\n    max_field_size: Union[int, None]\n\n\n@dataclasses.dataclass(frozen=True)\nclass ClientTimeout:\n    total: Optional[float] = None\n    connect: Optional[float] = None\n    sock_read: Optional[float] = None\n    sock_connect: Optional[float] = None\n    ceil_threshold: float = 5\n\n    # pool_queue_timeout: Optional[float] = None\n    # dns_resolution_timeout: Optional[float] = None\n    # socket_connect_timeout: Optional[float] = None\n    # connection_acquiring_timeout: Optional[float] = None\n    # new_connection_timeout: Optional[float] = None\n    # http_header_timeout: Optional[float] = None\n    # response_body_timeout: Optional[float] = None\n\n    # to create a timeout specific for a single request, either\n    # - create a completely new one to overwrite the default\n    # - or use https://docs.python.org/3/library/dataclasses.html#dataclasses.replace\n    # to overwrite the defaults\n\n\n# 5 Minute default read timeout\nDEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60)\n\n# https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2\nIDEMPOTENT_METHODS = frozenset({\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\", \"PUT\", \"DELETE\"})\n\n_RetType = TypeVar(\"_RetType\")\n_CharsetResolver = Callable[[ClientResponse, bytes], str]\n\n\n@final\nclass ClientSession:\n    \"\"\"First-class interface for making HTTP requests.\"\"\"\n\n    __slots__ = (\n        \"_base_url\",\n        \"_source_traceback\",\n        \"_connector\",\n        \"_loop\",\n        \"_cookie_jar\",\n        \"_connector_owner\",\n        \"_default_auth\",\n        \"_version\",\n        \"_json_serialize\",\n        \"_requote_redirect_url\",\n        \"_timeout\",\n        \"_raise_for_status\",\n        \"_auto_decompress\",\n        \"_trust_env\",\n        \"_default_headers\",\n        \"_skip_auto_headers\",\n        \"_request_class\",\n        \"_response_class\",\n        \"_ws_response_class\",\n        \"_trace_configs\",\n        \"_read_bufsize\",\n        \"_max_line_size\",\n        \"_max_field_size\",\n        \"_resolve_charset\",\n    )\n\n    def __init__(\n        self,\n        base_url: Optional[StrOrURL] = None,\n        *,\n        connector: Optional[BaseConnector] = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        json_serialize: JSONEncoder = json.dumps,\n        request_class: Type[ClientRequest] = ClientRequest,\n        response_class: Type[ClientResponse] = ClientResponse,\n        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,\n        version: HttpVersion = http.HttpVersion11,\n        cookie_jar: Optional[AbstractCookieJar] = None,\n        connector_owner: bool = True,\n        raise_for_status: Union[\n            bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = False,\n        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,\n        auto_decompress: bool = True,\n        trust_env: bool = False,\n        requote_redirect_url: bool = True,\n        trace_configs: Optional[List[TraceConfig[object]]] = None,\n        read_bufsize: int = 2**16,\n        max_line_size: int = 8190,\n        max_field_size: int = 8190,\n        fallback_charset_resolver: _CharsetResolver = lambda r, b: \"utf-8\",\n    ) -> None:\n        # We initialise _connector to None immediately, as it's referenced in __del__()\n        # and could cause issues if an exception occurs during initialisation.\n        self._connector: Optional[BaseConnector] = None\n        if base_url is None or isinstance(base_url, URL):\n            self._base_url: Optional[URL] = base_url\n        else:\n            self._base_url = URL(base_url)\n            assert (\n                self._base_url.origin() == self._base_url\n            ), \"Only absolute URLs without path part are supported\"\n\n        loop = asyncio.get_running_loop()\n\n        if timeout is sentinel or timeout is None:\n            timeout = DEFAULT_TIMEOUT\n        if not isinstance(timeout, ClientTimeout):\n            raise ValueError(\n                f\"timeout parameter cannot be of {type(timeout)} type, \"\n                \"please use 'timeout=ClientTimeout(...)'\",\n            )\n        self._timeout = timeout\n\n        if connector is None:\n            connector = TCPConnector()\n        # Initialize these three attrs before raising any exception,\n        # they are used in __del__\n        self._connector = connector\n        self._loop = loop\n        if loop.get_debug():\n            self._source_traceback: Optional[traceback.StackSummary] = (\n                traceback.extract_stack(sys._getframe(1))\n            )\n        else:\n            self._source_traceback = None\n\n        if connector._loop is not loop:\n            raise RuntimeError(\"Session and connector have to use same event loop\")\n\n        if cookie_jar is None:\n            cookie_jar = CookieJar()\n        self._cookie_jar = cookie_jar\n\n        if cookies is not None:\n            self._cookie_jar.update_cookies(cookies)\n\n        self._connector_owner = connector_owner\n        self._default_auth = auth\n        self._version = version\n        self._json_serialize = json_serialize\n        self._raise_for_status = raise_for_status\n        self._auto_decompress = auto_decompress\n        self._trust_env = trust_env\n        self._requote_redirect_url = requote_redirect_url\n        self._read_bufsize = read_bufsize\n        self._max_line_size = max_line_size\n        self._max_field_size = max_field_size\n\n        # Convert to list of tuples\n        if headers:\n            real_headers: CIMultiDict[str] = CIMultiDict(headers)\n        else:\n            real_headers = CIMultiDict()\n        self._default_headers: CIMultiDict[str] = real_headers\n        if skip_auto_headers is not None:\n            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)\n        else:\n            self._skip_auto_headers = frozenset()\n\n        self._request_class = request_class\n        self._response_class = response_class\n        self._ws_response_class = ws_response_class\n\n        self._trace_configs = trace_configs or []\n        for trace_config in self._trace_configs:\n            trace_config.freeze()\n\n        self._resolve_charset = fallback_charset_resolver\n\n    def __init_subclass__(cls: Type[\"ClientSession\"]) -> None:\n        raise TypeError(\n            \"Inheritance class {} from ClientSession \"\n            \"is forbidden\".format(cls.__name__)\n        )\n\n    def __del__(self, _warnings: Any = warnings) -> None:\n        if not self.closed:\n            _warnings.warn(\n                f\"Unclosed client session {self!r}\",\n                ResourceWarning,\n                source=self,\n            )\n            context = {\"client_session\": self, \"message\": \"Unclosed client session\"}\n            if self._source_traceback is not None:\n                context[\"source_traceback\"] = self._source_traceback\n            self._loop.call_exception_handler(context)\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def request(\n            self,\n            method: str,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def request(\n            self, method: str, url: StrOrURL, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP request.\"\"\"\n            return _RequestContextManager(self._request(method, url, **kwargs))\n\n    def _build_url(self, str_or_url: StrOrURL) -> URL:\n        url = URL(str_or_url)\n        if self._base_url is None:\n            return url\n        else:\n            assert not url.is_absolute() and url.path.startswith(\"/\")\n            return self._base_url.join(url)\n\n    async def _request(\n        self,\n        method: str,\n        str_or_url: StrOrURL,\n        *,\n        params: Optional[Mapping[str, str]] = None,\n        data: Any = None,\n        json: Any = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        allow_redirects: bool = True,\n        max_redirects: int = 10,\n        compress: Optional[str] = None,\n        chunked: Optional[bool] = None,\n        expect100: bool = False,\n        raise_for_status: Union[\n            None, bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = None,\n        read_until_eof: bool = True,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        trace_request_ctx: Optional[Mapping[str, str]] = None,\n        read_bufsize: Optional[int] = None,\n        auto_decompress: Optional[bool] = None,\n        max_line_size: Optional[int] = None,\n        max_field_size: Optional[int] = None,\n    ) -> ClientResponse:\n        # NOTE: timeout clamps existing connect and read timeouts.  We cannot\n        # set the default to None because we need to detect if the user wants\n        # to use the existing timeouts by setting timeout to None.\n\n        if self.closed:\n            raise RuntimeError(\"Session is closed\")\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        if data is not None and json is not None:\n            raise ValueError(\n                \"data and json parameters can not be used at the same time\"\n            )\n        elif json is not None:\n            data = payload.JsonPayload(json, dumps=self._json_serialize)\n\n        redirects = 0\n        history = []\n        version = self._version\n        params = params or {}\n\n        # Merge with default headers and transform to CIMultiDict\n        headers = self._prepare_headers(headers)\n        proxy_headers = self._prepare_headers(proxy_headers)\n\n        try:\n            url = self._build_url(str_or_url)\n        except ValueError as e:\n            raise InvalidUrlClientError(str_or_url) from e\n\n        assert self._connector is not None\n        if url.scheme not in self._connector.allowed_protocol_schema_set:\n            raise NonHttpUrlClientError(url)\n\n        skip_headers = set(self._skip_auto_headers)\n        if skip_auto_headers is not None:\n            for i in skip_auto_headers:\n                skip_headers.add(istr(i))\n\n        if proxy is not None:\n            try:\n                proxy = URL(proxy)\n            except ValueError as e:\n                raise InvalidURL(proxy) from e\n\n        if timeout is sentinel or timeout is None:\n            real_timeout: ClientTimeout = self._timeout\n        else:\n            real_timeout = timeout\n        # timeout is cumulative for all request operations\n        # (request, redirects, responses, data consuming)\n        tm = TimeoutHandle(\n            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold\n        )\n        handle = tm.start()\n\n        if read_bufsize is None:\n            read_bufsize = self._read_bufsize\n\n        if auto_decompress is None:\n            auto_decompress = self._auto_decompress\n\n        if max_line_size is None:\n            max_line_size = self._max_line_size\n\n        if max_field_size is None:\n            max_field_size = self._max_field_size\n\n        traces = [\n            Trace(\n                self,\n                trace_config,\n                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),\n            )\n            for trace_config in self._trace_configs\n        ]\n\n        for trace in traces:\n            await trace.send_request_start(method, url.update_query(params), headers)\n\n        timer = tm.timer()\n        try:\n            with timer:\n                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests\n                retry_persistent_connection = method in IDEMPOTENT_METHODS\n                while True:\n                    url, auth_from_url = strip_auth_from_url(url)\n                    if not url.raw_host:\n                        # NOTE: Bail early, otherwise, causes `InvalidURL` through\n                        # NOTE: `self._request_class()` below.\n                        err_exc_cls = (\n                            InvalidUrlRedirectClientError\n                            if redirects\n                            else InvalidUrlClientError\n                        )\n                        raise err_exc_cls(url)\n                    if auth and auth_from_url:\n                        raise ValueError(\n                            \"Cannot combine AUTH argument with \"\n                            \"credentials encoded in URL\"\n                        )\n\n                    if auth is None:\n                        auth = auth_from_url\n                    if auth is None:\n                        auth = self._default_auth\n                    # It would be confusing if we support explicit\n                    # Authorization header with auth argument\n                    if auth is not None and hdrs.AUTHORIZATION in headers:\n                        raise ValueError(\n                            \"Cannot combine AUTHORIZATION header \"\n                            \"with AUTH argument or credentials \"\n                            \"encoded in URL\"\n                        )\n\n                    all_cookies = self._cookie_jar.filter_cookies(url)\n\n                    if cookies is not None:\n                        tmp_cookie_jar = CookieJar()\n                        tmp_cookie_jar.update_cookies(cookies)\n                        req_cookies = tmp_cookie_jar.filter_cookies(url)\n                        if req_cookies:\n                            all_cookies.load(req_cookies)\n\n                    if proxy is not None:\n                        proxy = URL(proxy)\n                    elif self._trust_env:\n                        with suppress(LookupError):\n                            proxy, proxy_auth = get_env_proxy_for_url(url)\n\n                    req = self._request_class(\n                        method,\n                        url,\n                        params=params,\n                        headers=headers,\n                        skip_auto_headers=skip_headers if skip_headers else None,\n                        data=data,\n                        cookies=all_cookies,\n                        auth=auth,\n                        version=version,\n                        compress=compress,\n                        chunked=chunked,\n                        expect100=expect100,\n                        loop=self._loop,\n                        response_class=self._response_class,\n                        proxy=proxy,\n                        proxy_auth=proxy_auth,\n                        timer=timer,\n                        session=self,\n                        ssl=ssl,\n                        server_hostname=server_hostname,\n                        proxy_headers=proxy_headers,\n                        traces=traces,\n                        trust_env=self.trust_env,\n                    )\n\n                    # connection timeout\n                    try:\n                        async with ceil_timeout(\n                            real_timeout.connect,\n                            ceil_threshold=real_timeout.ceil_threshold,\n                        ):\n                            conn = await self._connector.connect(\n                                req, traces=traces, timeout=real_timeout\n                            )\n                    except asyncio.TimeoutError as exc:\n                        raise ConnectionTimeoutError(\n                            f\"Connection timeout to host {url}\"\n                        ) from exc\n\n                    assert conn.transport is not None\n\n                    assert conn.protocol is not None\n                    conn.protocol.set_response_params(\n                        timer=timer,\n                        skip_payload=method_must_be_empty_body(method),\n                        read_until_eof=read_until_eof,\n                        auto_decompress=auto_decompress,\n                        read_timeout=real_timeout.sock_read,\n                        read_bufsize=read_bufsize,\n                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,\n                        max_line_size=max_line_size,\n                        max_field_size=max_field_size,\n                    )\n\n                    try:\n                        try:\n                            resp = await req.send(conn)\n                            try:\n                                await resp.start(conn)\n                            except BaseException:\n                                resp.close()\n                                raise\n                        except BaseException:\n                            conn.close()\n                            raise\n                    except (ClientOSError, ServerDisconnectedError):\n                        if retry_persistent_connection:\n                            retry_persistent_connection = False\n                            continue\n                        raise\n                    except ClientError:\n                        raise\n                    except OSError as exc:\n                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                            raise\n                        raise ClientOSError(*exc.args) from exc\n\n                    self._cookie_jar.update_cookies(resp.cookies, resp.url)\n\n                    # redirects\n                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:\n                        for trace in traces:\n                            await trace.send_request_redirect(\n                                method, url.update_query(params), headers, resp\n                            )\n\n                        redirects += 1\n                        history.append(resp)\n                        if max_redirects and redirects >= max_redirects:\n                            resp.close()\n                            raise TooManyRedirects(\n                                history[0].request_info, tuple(history)\n                            )\n\n                        # For 301 and 302, mimic IE, now changed in RFC\n                        # https://github.com/kennethreitz/requests/pull/269\n                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (\n                            resp.status in (301, 302) and resp.method == hdrs.METH_POST\n                        ):\n                            method = hdrs.METH_GET\n                            data = None\n                            if headers.get(hdrs.CONTENT_LENGTH):\n                                headers.pop(hdrs.CONTENT_LENGTH)\n\n                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(\n                            hdrs.URI\n                        )\n                        if r_url is None:\n                            # see github.com/aio-libs/aiohttp/issues/2022\n                            break\n                        else:\n                            # reading from correct redirection\n                            # response is forbidden\n                            resp.release()\n\n                        try:\n                            parsed_redirect_url = URL(\n                                r_url, encoded=not self._requote_redirect_url\n                            )\n                        except ValueError as e:\n                            raise InvalidUrlRedirectClientError(\n                                r_url,\n                                \"Server attempted redirecting to a location that does not look like a URL\",\n                            ) from e\n\n                        scheme = parsed_redirect_url.scheme\n                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:\n                            resp.close()\n                            raise NonHttpUrlRedirectClientError(r_url)\n                        elif not scheme:\n                            parsed_redirect_url = url.join(parsed_redirect_url)\n\n                        is_same_host_https_redirect = (\n                            url.host == parsed_redirect_url.host\n                            and parsed_redirect_url.scheme == \"https\"\n                            and url.scheme == \"http\"\n                        )\n\n                        try:\n                            redirect_origin = parsed_redirect_url.origin()\n                        except ValueError as origin_val_err:\n                            raise InvalidUrlRedirectClientError(\n                                parsed_redirect_url,\n                                \"Invalid redirect URL origin\",\n                            ) from origin_val_err\n\n                        if (\n                            url.origin() != redirect_origin\n                            and not is_same_host_https_redirect\n                        ):\n                            auth = None\n                            headers.pop(hdrs.AUTHORIZATION, None)\n\n                        url = parsed_redirect_url\n                        params = {}\n                        resp.release()\n                        continue\n\n                    break\n\n            # check response status\n            if raise_for_status is None:\n                raise_for_status = self._raise_for_status\n\n            if raise_for_status is None:\n                pass\n            elif callable(raise_for_status):\n                await raise_for_status(resp)\n            elif raise_for_status:\n                resp.raise_for_status()\n\n            # register connection\n            if handle is not None:\n                if resp.connection is not None:\n                    resp.connection.add_callback(handle.cancel)\n                else:\n                    handle.cancel()\n\n            resp._history = tuple(history)\n\n            for trace in traces:\n                await trace.send_request_end(\n                    method, url.update_query(params), headers, resp\n                )\n            return resp\n\n        except BaseException as e:\n            # cleanup timer\n            tm.close()\n            if handle:\n                handle.cancel()\n                handle = None\n\n            for trace in traces:\n                await trace.send_request_exception(\n                    method, url.update_query(params), headers, e\n                )\n            raise\n\n    def ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> \"_WSRequestContextManager\":\n        \"\"\"Initiate websocket connection.\"\"\"\n        return _WSRequestContextManager(\n            self._ws_connect(\n                url,\n                method=method,\n                protocols=protocols,\n                timeout=timeout,\n                receive_timeout=receive_timeout,\n                autoclose=autoclose,\n                autoping=autoping,\n                heartbeat=heartbeat,\n                auth=auth,\n                origin=origin,\n                params=params,\n                headers=headers,\n                proxy=proxy,\n                proxy_auth=proxy_auth,\n                ssl=ssl,\n                server_hostname=server_hostname,\n                proxy_headers=proxy_headers,\n                compress=compress,\n                max_msg_size=max_msg_size,\n            )\n        )\n\n    async def _ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> ClientWebSocketResponse:\n        if timeout is sentinel or timeout is None:\n            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT\n        else:\n            if isinstance(timeout, ClientWSTimeout):\n                ws_timeout = timeout\n            else:\n                warnings.warn(\n                    \"parameter 'timeout' of type 'float' \"\n                    \"is deprecated, please use \"\n                    \"'timeout=ClientWSTimeout(ws_close=...)'\",\n                    DeprecationWarning,\n                    stacklevel=2,\n                )\n                ws_timeout = ClientWSTimeout(ws_close=timeout)\n\n        if receive_timeout is not None:\n            warnings.warn(\n                \"float parameter 'receive_timeout' \"\n                \"is deprecated, please use parameter \"\n                \"'timeout=ClientWSTimeout(ws_receive=...)'\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)\n\n        if headers is None:\n            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        default_headers = {\n            hdrs.UPGRADE: \"websocket\",\n            hdrs.CONNECTION: \"Upgrade\",\n            hdrs.SEC_WEBSOCKET_VERSION: \"13\",\n        }\n\n        for key, value in default_headers.items():\n            real_headers.setdefault(key, value)\n\n        sec_key = base64.b64encode(os.urandom(16))\n        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()\n\n        if protocols:\n            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = \",\".join(protocols)\n        if origin is not None:\n            real_headers[hdrs.ORIGIN] = origin\n        if compress:\n            extstr = ws_ext_gen(compress=compress)\n            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        # send request\n        resp = await self.request(\n            method,\n            url,\n            params=params,\n            headers=real_headers,\n            read_until_eof=False,\n            auth=auth,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            ssl=ssl,\n            server_hostname=server_hostname,\n            proxy_headers=proxy_headers,\n        )\n\n        try:\n            # check handshake\n            if resp.status != 101:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid response status\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.UPGRADE, \"\").lower() != \"websocket\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid upgrade header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.CONNECTION, \"\").lower() != \"upgrade\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid connection header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # key calculation\n            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, \"\")\n            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()\n            if r_key != match:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid challenge response\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # websocket protocol\n            protocol = None\n            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:\n                resp_protocols = [\n                    proto.strip()\n                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(\",\")\n                ]\n\n                for proto in resp_protocols:\n                    if proto in protocols:\n                        protocol = proto\n                        break\n\n            # websocket compress\n            notakeover = False\n            if compress:\n                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)\n                if compress_hdrs:\n                    try:\n                        compress, notakeover = ws_ext_parse(compress_hdrs)\n                    except WSHandshakeError as exc:\n                        raise WSServerHandshakeError(\n                            resp.request_info,\n                            resp.history,\n                            message=exc.args[0],\n                            status=resp.status,\n                            headers=resp.headers,\n                        ) from exc\n                else:\n                    compress = 0\n                    notakeover = False\n\n            conn = resp.connection\n            assert conn is not None\n            conn_proto = conn.protocol\n            assert conn_proto is not None\n\n            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater\n            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible\n            if ws_timeout.ws_receive is None:\n                # Reset regardless\n                conn_proto.read_timeout = None\n            elif conn_proto.read_timeout is not None:\n                conn_proto.read_timeout = max(\n                    ws_timeout.ws_receive, conn_proto.read_timeout\n                )\n\n            transport = conn.transport\n            assert transport is not None\n            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(\n                conn_proto, 2**16, loop=self._loop\n            )\n            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)\n            writer = WebSocketWriter(\n                conn_proto,\n                transport,\n                use_mask=True,\n                compress=compress,\n                notakeover=notakeover,\n            )\n        except BaseException:\n            resp.close()\n            raise\n        else:\n            return self._ws_response_class(\n                reader,\n                writer,\n                protocol,\n                resp,\n                ws_timeout,\n                autoclose,\n                autoping,\n                self._loop,\n                heartbeat=heartbeat,\n                compress=compress,\n                client_notakeover=notakeover,\n            )\n\n    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> \"CIMultiDict[str]\":\n        \"\"\"Add default headers and transform it to CIMultiDict\"\"\"\n        # Convert headers to MultiDict\n        result = CIMultiDict(self._default_headers)\n        if headers:\n            if not isinstance(headers, (MultiDictProxy, MultiDict)):\n                headers = CIMultiDict(headers)\n            added_names: Set[str] = set()\n            for key, value in headers.items():\n                if key in added_names:\n                    result.add(key, value)\n                else:\n                    result[key] = value\n                    added_names.add(key)\n        return result\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def get(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def options(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def head(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def post(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def put(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def patch(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def delete(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def get(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP GET request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def options(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP OPTIONS request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def head(\n            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP HEAD request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def post(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP POST request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_POST, url, data=data, **kwargs)\n            )\n\n        def put(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PUT request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PUT, url, data=data, **kwargs)\n            )\n\n        def patch(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PATCH request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)\n            )\n\n        def delete(self, url: StrOrURL, **kwargs: Any) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP DELETE request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_DELETE, url, **kwargs)\n            )\n\n    async def close(self) -> None:\n        \"\"\"Close underlying connector.\n\n        Release all acquired resources.\n        \"\"\"\n        if not self.closed:\n            if self._connector is not None and self._connector_owner:\n                await self._connector.close()\n            self._connector = None\n\n    @property\n    def closed(self) -> bool:\n        \"\"\"Is client session closed.\n\n        A readonly property.\n        \"\"\"\n        return self._connector is None or self._connector.closed\n\n    @property\n    def connector(self) -> Optional[BaseConnector]:\n        \"\"\"Connector instance used for the session.\"\"\"\n        return self._connector\n\n    @property\n    def cookie_jar(self) -> AbstractCookieJar:\n        \"\"\"The session cookies.\"\"\"\n        return self._cookie_jar\n\n    @property\n    def version(self) -> Tuple[int, int]:\n        \"\"\"The session HTTP protocol version.\"\"\"\n        return self._version\n\n    @property\n    def requote_redirect_url(self) -> bool:\n        \"\"\"Do URL requoting on redirection handling.\"\"\"\n        return self._requote_redirect_url\n\n    @property\n    def timeout(self) -> ClientTimeout:\n        \"\"\"Timeout for the session.\"\"\"\n        return self._timeout\n\n    @property\n    def headers(self) -> \"CIMultiDict[str]\":\n        \"\"\"The default headers of the client session.\"\"\"\n        return self._default_headers\n\n    @property\n    def skip_auto_headers(self) -> FrozenSet[istr]:\n        \"\"\"Headers for which autogeneration should be skipped\"\"\"\n        return self._skip_auto_headers\n\n    @property\n    def auth(self) -> Optional[BasicAuth]:\n        \"\"\"An object that represents HTTP Basic Authorization\"\"\"\n        return self._default_auth\n\n    @property\n    def json_serialize(self) -> JSONEncoder:\n        \"\"\"Json serializer callable\"\"\"\n        return self._json_serialize\n\n    @property\n    def connector_owner(self) -> bool:\n        \"\"\"Should connector be closed on session closing\"\"\"\n        return self._connector_owner\n\n    @property\n    def raise_for_status(\n        self,\n    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:\n        \"\"\"Should `ClientResponse.raise_for_status()` be called for each response.\"\"\"\n        return self._raise_for_status\n\n    @property\n    def auto_decompress(self) -> bool:\n        \"\"\"Should the body response be automatically decompressed.\"\"\"\n        return self._auto_decompress\n\n    @property\n    def trust_env(self) -> bool:\n        \"\"\"\n        Should proxies information from environment or netrc be trusted.\n\n        Information is from HTTP_PROXY / HTTPS_PROXY environment variables\n        or ~/.netrc file if present.\n        \"\"\"\n        return self._trust_env\n\n    @property\n    def trace_configs(self) -> List[TraceConfig[Any]]:\n        \"\"\"A list of TraceConfig instances used for client tracing\"\"\"\n        return self._trace_configs\n\n    def detach(self) -> None:\n        \"\"\"Detach connector from session without closing the former.\n\n        Session is switched to closed state anyway.\n        \"\"\"\n        self._connector = None\n\n    async def __aenter__(self) -> \"ClientSession\":\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        await self.close()\n\n\nclass _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]):\n    __slots__ = (\"_coro\", \"_resp\")\n\n    def __init__(self, coro: Coroutine[\"asyncio.Future[Any]\", None, _RetType]) -> None:\n        self._coro = coro\n\n    def send(self, arg: None) -> \"asyncio.Future[Any]\":\n        return self._coro.send(arg)\n\n    def throw(self, *args: Any, **kwargs: Any) -> \"asyncio.Future[Any]\":\n        return self._coro.throw(*args, **kwargs)\n\n    def close(self) -> None:\n        return self._coro.close()\n\n    def __await__(self) -> Generator[Any, None, _RetType]:\n        ret = self._coro.__await__()\n        return ret\n\n    def __iter__(self) -> Generator[Any, None, _RetType]:\n        return self.__await__()\n\n    async def __aenter__(self) -> _RetType:\n        self._resp = await self._coro\n        return self._resp\n\n\nclass _RequestContextManager(_BaseRequestContextManager[ClientResponse]):\n    __slots__ = ()\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        # We're basing behavior on the exception as it can be caused by\n        # user code unrelated to the status of the connection.  If you\n        # would like to close a connection you must do that\n        # explicitly.  Otherwise connection error handling should kick in\n        # and close/recycle the connection as required.\n        self._resp.release()\n        await self._resp.wait_for_close()\n\n\nclass _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]):\n    __slots__ = ()\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        await self._resp.close()\n\n\nclass _SessionRequestContextManager:\n    __slots__ = (\"_coro\", \"_resp\", \"_session\")\n\n    def __init__(\n        self,\n        coro: Coroutine[\"asyncio.Future[Any]\", None, ClientResponse],\n        session: ClientSession,\n    ) -> None:\n        self._coro = coro\n        self._resp: Optional[ClientResponse] = None\n        self._session = session\n\n    async def __aenter__(self) -> ClientResponse:\n        try:\n            self._resp = await self._coro\n        except BaseException:\n            await self._session.close()\n            raise\n        else:\n            return self._resp\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        assert self._resp is not None\n        self._resp.close()\n        await self._session.close()\n\n\ndef request(\n    method: str,\n    url: StrOrURL,\n    *,\n    params: Optional[Mapping[str, str]] = None,\n    data: Any = None,\n    json: Any = None,\n    headers: Optional[LooseHeaders] = None,\n    skip_auto_headers: Optional[Iterable[str]] = None,\n    auth: Optional[BasicAuth] = None,\n    allow_redirects: bool = True,\n    max_redirects: int = 10,\n    compress: Optional[str] = None,\n    chunked: Optional[bool] = None,\n    expect100: bool = False,\n    raise_for_status: Optional[bool] = None,\n    read_until_eof: bool = True,\n    proxy: Optional[StrOrURL] = None,\n    proxy_auth: Optional[BasicAuth] = None,\n    timeout: Union[ClientTimeout, _SENTINEL] = sentinel,\n    cookies: Optional[LooseCookies] = None,\n    version: HttpVersion = http.HttpVersion11,\n    connector: Optional[BaseConnector] = None,\n    read_bufsize: Optional[int] = None,\n    max_line_size: int = 8190,\n    max_field_size: int = 8190,\n) -> _SessionRequestContextManager:\n    \"\"\"Constructs and sends a request.\n\n    Returns response object.\n    method - HTTP method\n    url - request url\n    params - (optional) Dictionary or bytes to be sent in the query\n      string of the new request\n    data - (optional) Dictionary, bytes, or file-like object to\n      send in the body of the request\n    json - (optional) Any json compatible python object\n    headers - (optional) Dictionary of HTTP Headers to send with\n      the request\n    cookies - (optional) Dict object to send with the request\n    auth - (optional) BasicAuth named tuple represent HTTP Basic Auth\n    auth - aiohttp.helpers.BasicAuth\n    allow_redirects - (optional) If set to False, do not follow\n      redirects\n    version - Request HTTP version.\n    compress - Set to True if request has to be compressed\n       with deflate encoding.\n    chunked - Set to chunk size for chunked transfer encoding.\n    expect100 - Expect 100-continue response from server.\n    connector - BaseConnector sub-class instance to support\n       connection pooling.\n    read_until_eof - Read response until eof if response\n       does not have Content-Length header.\n    loop - Optional event loop.\n    timeout - Optional ClientTimeout settings structure, 5min\n       total timeout by default.\n    Usage::\n      >>> import aiohttp\n      >>> async with aiohttp.request('GET', 'http://python.org/') as resp:\n      ...    print(resp)\n      ...    data = await resp.read()\n      <ClientResponse(https://www.python.org/) [200 OK]>\n    \"\"\"\n    connector_owner = False\n    if connector is None:\n        connector_owner = True\n        connector = TCPConnector(force_close=True)\n\n    session = ClientSession(\n        cookies=cookies,\n        version=version,\n        timeout=timeout,\n        connector=connector,\n        connector_owner=connector_owner,\n    )\n\n    return _SessionRequestContextManager(\n        session._request(\n            method,\n            url,\n            params=params,\n            data=data,\n            json=json,\n            headers=headers,\n            skip_auto_headers=skip_auto_headers,\n            auth=auth,\n            allow_redirects=allow_redirects,\n            max_redirects=max_redirects,\n            compress=compress,\n            chunked=chunked,\n            expect100=expect100,\n            raise_for_status=raise_for_status,\n            read_until_eof=read_until_eof,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            read_bufsize=read_bufsize,\n            max_line_size=max_line_size,\n            max_field_size=max_field_size,\n        ),\n        session,\n    )\n",
            "new_file_content": "\"\"\"HTTP Client for asyncio.\"\"\"\n\nimport asyncio\nimport base64\nimport dataclasses\nimport hashlib\nimport json\nimport os\nimport sys\nimport traceback\nimport warnings\nfrom contextlib import suppress\nfrom types import TracebackType\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Awaitable,\n    Callable,\n    Collection,\n    Coroutine,\n    Final,\n    FrozenSet,\n    Generator,\n    Generic,\n    Iterable,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n    TypedDict,\n    TypeVar,\n    Union,\n    final,\n)\n\nfrom multidict import CIMultiDict, MultiDict, MultiDictProxy, istr\nfrom yarl import URL\n\nfrom . import hdrs, http, payload\nfrom .abc import AbstractCookieJar\nfrom .client_exceptions import (\n    ClientConnectionError,\n    ClientConnectorCertificateError,\n    ClientConnectorError,\n    ClientConnectorSSLError,\n    ClientError,\n    ClientHttpProxyError,\n    ClientOSError,\n    ClientPayloadError,\n    ClientProxyConnectionError,\n    ClientResponseError,\n    ClientSSLError,\n    ConnectionTimeoutError,\n    ContentTypeError,\n    InvalidURL,\n    InvalidUrlClientError,\n    InvalidUrlRedirectClientError,\n    NonHttpUrlClientError,\n    NonHttpUrlRedirectClientError,\n    RedirectClientError,\n    ServerConnectionError,\n    ServerDisconnectedError,\n    ServerFingerprintMismatch,\n    ServerTimeoutError,\n    SocketTimeoutError,\n    TooManyRedirects,\n    WSServerHandshakeError,\n)\nfrom .client_reqrep import (\n    SSL_ALLOWED_TYPES,\n    ClientRequest,\n    ClientResponse,\n    Fingerprint,\n    RequestInfo,\n)\nfrom .client_ws import (\n    DEFAULT_WS_CLIENT_TIMEOUT,\n    ClientWebSocketResponse,\n    ClientWSTimeout,\n)\nfrom .connector import (\n    HTTP_AND_EMPTY_SCHEMA_SET,\n    BaseConnector,\n    NamedPipeConnector,\n    TCPConnector,\n    UnixConnector,\n)\nfrom .cookiejar import CookieJar\nfrom .helpers import (\n    _SENTINEL,\n    BasicAuth,\n    TimeoutHandle,\n    ceil_timeout,\n    get_env_proxy_for_url,\n    method_must_be_empty_body,\n    sentinel,\n    strip_auth_from_url,\n)\nfrom .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter\nfrom .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse\nfrom .streams import FlowControlDataQueue\nfrom .tracing import Trace, TraceConfig\nfrom .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL\n\n__all__ = (\n    # client_exceptions\n    \"ClientConnectionError\",\n    \"ClientConnectorCertificateError\",\n    \"ClientConnectorError\",\n    \"ClientConnectorSSLError\",\n    \"ClientError\",\n    \"ClientHttpProxyError\",\n    \"ClientOSError\",\n    \"ClientPayloadError\",\n    \"ClientProxyConnectionError\",\n    \"ClientResponseError\",\n    \"ClientSSLError\",\n    \"ConnectionTimeoutError\",\n    \"ContentTypeError\",\n    \"InvalidURL\",\n    \"InvalidUrlClientError\",\n    \"RedirectClientError\",\n    \"NonHttpUrlClientError\",\n    \"InvalidUrlRedirectClientError\",\n    \"NonHttpUrlRedirectClientError\",\n    \"ServerConnectionError\",\n    \"ServerDisconnectedError\",\n    \"ServerFingerprintMismatch\",\n    \"ServerTimeoutError\",\n    \"SocketTimeoutError\",\n    \"TooManyRedirects\",\n    \"WSServerHandshakeError\",\n    # client_reqrep\n    \"ClientRequest\",\n    \"ClientResponse\",\n    \"Fingerprint\",\n    \"RequestInfo\",\n    # connector\n    \"BaseConnector\",\n    \"TCPConnector\",\n    \"UnixConnector\",\n    \"NamedPipeConnector\",\n    # client_ws\n    \"ClientWebSocketResponse\",\n    # client\n    \"ClientSession\",\n    \"ClientTimeout\",\n    \"ClientWSTimeout\",\n    \"request\",\n)\n\n\nif TYPE_CHECKING:\n    from ssl import SSLContext\nelse:\n    SSLContext = None\n\nif sys.version_info >= (3, 11) and TYPE_CHECKING:\n    from typing import Unpack\n\n\nclass _RequestOptions(TypedDict, total=False):\n    params: Union[Mapping[str, Union[str, int]], str, None]\n    data: Any\n    json: Any\n    cookies: Union[LooseCookies, None]\n    headers: Union[LooseHeaders, None]\n    skip_auto_headers: Union[Iterable[str], None]\n    auth: Union[BasicAuth, None]\n    allow_redirects: bool\n    max_redirects: int\n    compress: Union[str, None]\n    chunked: Union[bool, None]\n    expect100: bool\n    raise_for_status: Union[None, bool, Callable[[ClientResponse], Awaitable[None]]]\n    read_until_eof: bool\n    proxy: Union[StrOrURL, None]\n    proxy_auth: Union[BasicAuth, None]\n    timeout: \"Union[ClientTimeout, _SENTINEL, None]\"\n    ssl: Union[SSLContext, bool, Fingerprint]\n    server_hostname: Union[str, None]\n    proxy_headers: Union[LooseHeaders, None]\n    trace_request_ctx: Union[Mapping[str, str], None]\n    read_bufsize: Union[int, None]\n    auto_decompress: Union[bool, None]\n    max_line_size: Union[int, None]\n    max_field_size: Union[int, None]\n\n\n@dataclasses.dataclass(frozen=True)\nclass ClientTimeout:\n    total: Optional[float] = None\n    connect: Optional[float] = None\n    sock_read: Optional[float] = None\n    sock_connect: Optional[float] = None\n    ceil_threshold: float = 5\n\n    # pool_queue_timeout: Optional[float] = None\n    # dns_resolution_timeout: Optional[float] = None\n    # socket_connect_timeout: Optional[float] = None\n    # connection_acquiring_timeout: Optional[float] = None\n    # new_connection_timeout: Optional[float] = None\n    # http_header_timeout: Optional[float] = None\n    # response_body_timeout: Optional[float] = None\n\n    # to create a timeout specific for a single request, either\n    # - create a completely new one to overwrite the default\n    # - or use https://docs.python.org/3/library/dataclasses.html#dataclasses.replace\n    # to overwrite the defaults\n\n\n# 5 Minute default read timeout\nDEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60)\n\n# https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2\nIDEMPOTENT_METHODS = frozenset({\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\", \"PUT\", \"DELETE\"})\n\n_RetType = TypeVar(\"_RetType\")\n_CharsetResolver = Callable[[ClientResponse, bytes], str]\n\n\n@final\nclass ClientSession:\n    \"\"\"First-class interface for making HTTP requests.\"\"\"\n\n    __slots__ = (\n        \"_base_url\",\n        \"_source_traceback\",\n        \"_connector\",\n        \"_loop\",\n        \"_cookie_jar\",\n        \"_connector_owner\",\n        \"_default_auth\",\n        \"_version\",\n        \"_json_serialize\",\n        \"_requote_redirect_url\",\n        \"_timeout\",\n        \"_raise_for_status\",\n        \"_auto_decompress\",\n        \"_trust_env\",\n        \"_default_headers\",\n        \"_skip_auto_headers\",\n        \"_request_class\",\n        \"_response_class\",\n        \"_ws_response_class\",\n        \"_trace_configs\",\n        \"_read_bufsize\",\n        \"_max_line_size\",\n        \"_max_field_size\",\n        \"_resolve_charset\",\n    )\n\n    def __init__(\n        self,\n        base_url: Optional[StrOrURL] = None,\n        *,\n        connector: Optional[BaseConnector] = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        json_serialize: JSONEncoder = json.dumps,\n        request_class: Type[ClientRequest] = ClientRequest,\n        response_class: Type[ClientResponse] = ClientResponse,\n        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,\n        version: HttpVersion = http.HttpVersion11,\n        cookie_jar: Optional[AbstractCookieJar] = None,\n        connector_owner: bool = True,\n        raise_for_status: Union[\n            bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = False,\n        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,\n        auto_decompress: bool = True,\n        trust_env: bool = False,\n        requote_redirect_url: bool = True,\n        trace_configs: Optional[List[TraceConfig[object]]] = None,\n        read_bufsize: int = 2**16,\n        max_line_size: int = 8190,\n        max_field_size: int = 8190,\n        fallback_charset_resolver: _CharsetResolver = lambda r, b: \"utf-8\",\n    ) -> None:\n        # We initialise _connector to None immediately, as it's referenced in __del__()\n        # and could cause issues if an exception occurs during initialisation.\n        self._connector: Optional[BaseConnector] = None\n        if base_url is None or isinstance(base_url, URL):\n            self._base_url: Optional[URL] = base_url\n        else:\n            self._base_url = URL(base_url)\n            assert (\n                self._base_url.origin() == self._base_url\n            ), \"Only absolute URLs without path part are supported\"\n\n        loop = asyncio.get_running_loop()\n\n        if timeout is sentinel or timeout is None:\n            timeout = DEFAULT_TIMEOUT\n        if not isinstance(timeout, ClientTimeout):\n            raise ValueError(\n                f\"timeout parameter cannot be of {type(timeout)} type, \"\n                \"please use 'timeout=ClientTimeout(...)'\",\n            )\n        self._timeout = timeout\n\n        if connector is None:\n            connector = TCPConnector()\n        # Initialize these three attrs before raising any exception,\n        # they are used in __del__\n        self._connector = connector\n        self._loop = loop\n        if loop.get_debug():\n            self._source_traceback: Optional[traceback.StackSummary] = (\n                traceback.extract_stack(sys._getframe(1))\n            )\n        else:\n            self._source_traceback = None\n\n        if connector._loop is not loop:\n            raise RuntimeError(\"Session and connector have to use same event loop\")\n\n        if cookie_jar is None:\n            cookie_jar = CookieJar()\n        self._cookie_jar = cookie_jar\n\n        if cookies is not None:\n            self._cookie_jar.update_cookies(cookies)\n\n        self._connector_owner = connector_owner\n        self._default_auth = auth\n        self._version = version\n        self._json_serialize = json_serialize\n        self._raise_for_status = raise_for_status\n        self._auto_decompress = auto_decompress\n        self._trust_env = trust_env\n        self._requote_redirect_url = requote_redirect_url\n        self._read_bufsize = read_bufsize\n        self._max_line_size = max_line_size\n        self._max_field_size = max_field_size\n\n        # Convert to list of tuples\n        if headers:\n            real_headers: CIMultiDict[str] = CIMultiDict(headers)\n        else:\n            real_headers = CIMultiDict()\n        self._default_headers: CIMultiDict[str] = real_headers\n        if skip_auto_headers is not None:\n            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)\n        else:\n            self._skip_auto_headers = frozenset()\n\n        self._request_class = request_class\n        self._response_class = response_class\n        self._ws_response_class = ws_response_class\n\n        self._trace_configs = trace_configs or []\n        for trace_config in self._trace_configs:\n            trace_config.freeze()\n\n        self._resolve_charset = fallback_charset_resolver\n\n    def __init_subclass__(cls: Type[\"ClientSession\"]) -> None:\n        raise TypeError(\n            \"Inheritance class {} from ClientSession \"\n            \"is forbidden\".format(cls.__name__)\n        )\n\n    def __del__(self, _warnings: Any = warnings) -> None:\n        if not self.closed:\n            _warnings.warn(\n                f\"Unclosed client session {self!r}\",\n                ResourceWarning,\n                source=self,\n            )\n            context = {\"client_session\": self, \"message\": \"Unclosed client session\"}\n            if self._source_traceback is not None:\n                context[\"source_traceback\"] = self._source_traceback\n            self._loop.call_exception_handler(context)\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def request(\n            self,\n            method: str,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def request(\n            self, method: str, url: StrOrURL, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP request.\"\"\"\n            return _RequestContextManager(self._request(method, url, **kwargs))\n\n    def _build_url(self, str_or_url: StrOrURL) -> URL:\n        url = URL(str_or_url)\n        if self._base_url is None:\n            return url\n        else:\n            assert not url.is_absolute() and url.path.startswith(\"/\")\n            return self._base_url.join(url)\n\n    async def _request(\n        self,\n        method: str,\n        str_or_url: StrOrURL,\n        *,\n        params: Optional[Mapping[str, str]] = None,\n        data: Any = None,\n        json: Any = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        allow_redirects: bool = True,\n        max_redirects: int = 10,\n        compress: Optional[str] = None,\n        chunked: Optional[bool] = None,\n        expect100: bool = False,\n        raise_for_status: Union[\n            None, bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = None,\n        read_until_eof: bool = True,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        trace_request_ctx: Optional[Mapping[str, str]] = None,\n        read_bufsize: Optional[int] = None,\n        auto_decompress: Optional[bool] = None,\n        max_line_size: Optional[int] = None,\n        max_field_size: Optional[int] = None,\n    ) -> ClientResponse:\n        # NOTE: timeout clamps existing connect and read timeouts.  We cannot\n        # set the default to None because we need to detect if the user wants\n        # to use the existing timeouts by setting timeout to None.\n\n        if self.closed:\n            raise RuntimeError(\"Session is closed\")\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        if data is not None and json is not None:\n            raise ValueError(\n                \"data and json parameters can not be used at the same time\"\n            )\n        elif json is not None:\n            data = payload.JsonPayload(json, dumps=self._json_serialize)\n\n        redirects = 0\n        history = []\n        version = self._version\n        params = params or {}\n\n        # Merge with default headers and transform to CIMultiDict\n        headers = self._prepare_headers(headers)\n        proxy_headers = self._prepare_headers(proxy_headers)\n\n        try:\n            url = self._build_url(str_or_url)\n        except ValueError as e:\n            raise InvalidUrlClientError(str_or_url) from e\n\n        assert self._connector is not None\n        if url.scheme not in self._connector.allowed_protocol_schema_set:\n            raise NonHttpUrlClientError(url)\n\n        skip_headers = set(self._skip_auto_headers)\n        if skip_auto_headers is not None:\n            for i in skip_auto_headers:\n                skip_headers.add(istr(i))\n\n        if proxy is not None:\n            try:\n                proxy = URL(proxy)\n            except ValueError as e:\n                raise InvalidURL(proxy) from e\n\n        if timeout is sentinel or timeout is None:\n            real_timeout: ClientTimeout = self._timeout\n        else:\n            real_timeout = timeout\n        # timeout is cumulative for all request operations\n        # (request, redirects, responses, data consuming)\n        tm = TimeoutHandle(\n            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold\n        )\n        handle = tm.start()\n\n        if read_bufsize is None:\n            read_bufsize = self._read_bufsize\n\n        if auto_decompress is None:\n            auto_decompress = self._auto_decompress\n\n        if max_line_size is None:\n            max_line_size = self._max_line_size\n\n        if max_field_size is None:\n            max_field_size = self._max_field_size\n\n        traces = [\n            Trace(\n                self,\n                trace_config,\n                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),\n            )\n            for trace_config in self._trace_configs\n        ]\n\n        for trace in traces:\n            await trace.send_request_start(method, url.update_query(params), headers)\n\n        timer = tm.timer()\n        try:\n            with timer:\n                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests\n                retry_persistent_connection = method in IDEMPOTENT_METHODS\n                while True:\n                    url, auth_from_url = strip_auth_from_url(url)\n                    if not url.raw_host:\n                        # NOTE: Bail early, otherwise, causes `InvalidURL` through\n                        # NOTE: `self._request_class()` below.\n                        err_exc_cls = (\n                            InvalidUrlRedirectClientError\n                            if redirects\n                            else InvalidUrlClientError\n                        )\n                        raise err_exc_cls(url)\n                    if auth and auth_from_url:\n                        raise ValueError(\n                            \"Cannot combine AUTH argument with \"\n                            \"credentials encoded in URL\"\n                        )\n\n                    if auth is None:\n                        auth = auth_from_url\n\n                    if auth is None and (\n                        not self._base_url or self._base_url.origin() == url.origin()\n                    ):\n                        auth = self._default_auth\n                    # It would be confusing if we support explicit\n                    # Authorization header with auth argument\n                    if auth is not None and hdrs.AUTHORIZATION in headers:\n                        raise ValueError(\n                            \"Cannot combine AUTHORIZATION header \"\n                            \"with AUTH argument or credentials \"\n                            \"encoded in URL\"\n                        )\n\n                    all_cookies = self._cookie_jar.filter_cookies(url)\n\n                    if cookies is not None:\n                        tmp_cookie_jar = CookieJar()\n                        tmp_cookie_jar.update_cookies(cookies)\n                        req_cookies = tmp_cookie_jar.filter_cookies(url)\n                        if req_cookies:\n                            all_cookies.load(req_cookies)\n\n                    if proxy is not None:\n                        proxy = URL(proxy)\n                    elif self._trust_env:\n                        with suppress(LookupError):\n                            proxy, proxy_auth = get_env_proxy_for_url(url)\n\n                    req = self._request_class(\n                        method,\n                        url,\n                        params=params,\n                        headers=headers,\n                        skip_auto_headers=skip_headers if skip_headers else None,\n                        data=data,\n                        cookies=all_cookies,\n                        auth=auth,\n                        version=version,\n                        compress=compress,\n                        chunked=chunked,\n                        expect100=expect100,\n                        loop=self._loop,\n                        response_class=self._response_class,\n                        proxy=proxy,\n                        proxy_auth=proxy_auth,\n                        timer=timer,\n                        session=self,\n                        ssl=ssl,\n                        server_hostname=server_hostname,\n                        proxy_headers=proxy_headers,\n                        traces=traces,\n                        trust_env=self.trust_env,\n                    )\n\n                    # connection timeout\n                    try:\n                        async with ceil_timeout(\n                            real_timeout.connect,\n                            ceil_threshold=real_timeout.ceil_threshold,\n                        ):\n                            conn = await self._connector.connect(\n                                req, traces=traces, timeout=real_timeout\n                            )\n                    except asyncio.TimeoutError as exc:\n                        raise ConnectionTimeoutError(\n                            f\"Connection timeout to host {url}\"\n                        ) from exc\n\n                    assert conn.transport is not None\n\n                    assert conn.protocol is not None\n                    conn.protocol.set_response_params(\n                        timer=timer,\n                        skip_payload=method_must_be_empty_body(method),\n                        read_until_eof=read_until_eof,\n                        auto_decompress=auto_decompress,\n                        read_timeout=real_timeout.sock_read,\n                        read_bufsize=read_bufsize,\n                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,\n                        max_line_size=max_line_size,\n                        max_field_size=max_field_size,\n                    )\n\n                    try:\n                        try:\n                            resp = await req.send(conn)\n                            try:\n                                await resp.start(conn)\n                            except BaseException:\n                                resp.close()\n                                raise\n                        except BaseException:\n                            conn.close()\n                            raise\n                    except (ClientOSError, ServerDisconnectedError):\n                        if retry_persistent_connection:\n                            retry_persistent_connection = False\n                            continue\n                        raise\n                    except ClientError:\n                        raise\n                    except OSError as exc:\n                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                            raise\n                        raise ClientOSError(*exc.args) from exc\n\n                    self._cookie_jar.update_cookies(resp.cookies, resp.url)\n\n                    # redirects\n                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:\n                        for trace in traces:\n                            await trace.send_request_redirect(\n                                method, url.update_query(params), headers, resp\n                            )\n\n                        redirects += 1\n                        history.append(resp)\n                        if max_redirects and redirects >= max_redirects:\n                            resp.close()\n                            raise TooManyRedirects(\n                                history[0].request_info, tuple(history)\n                            )\n\n                        # For 301 and 302, mimic IE, now changed in RFC\n                        # https://github.com/kennethreitz/requests/pull/269\n                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (\n                            resp.status in (301, 302) and resp.method == hdrs.METH_POST\n                        ):\n                            method = hdrs.METH_GET\n                            data = None\n                            if headers.get(hdrs.CONTENT_LENGTH):\n                                headers.pop(hdrs.CONTENT_LENGTH)\n\n                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(\n                            hdrs.URI\n                        )\n                        if r_url is None:\n                            # see github.com/aio-libs/aiohttp/issues/2022\n                            break\n                        else:\n                            # reading from correct redirection\n                            # response is forbidden\n                            resp.release()\n\n                        try:\n                            parsed_redirect_url = URL(\n                                r_url, encoded=not self._requote_redirect_url\n                            )\n                        except ValueError as e:\n                            raise InvalidUrlRedirectClientError(\n                                r_url,\n                                \"Server attempted redirecting to a location that does not look like a URL\",\n                            ) from e\n\n                        scheme = parsed_redirect_url.scheme\n                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:\n                            resp.close()\n                            raise NonHttpUrlRedirectClientError(r_url)\n                        elif not scheme:\n                            parsed_redirect_url = url.join(parsed_redirect_url)\n\n                        is_same_host_https_redirect = (\n                            url.host == parsed_redirect_url.host\n                            and parsed_redirect_url.scheme == \"https\"\n                            and url.scheme == \"http\"\n                        )\n\n                        try:\n                            redirect_origin = parsed_redirect_url.origin()\n                        except ValueError as origin_val_err:\n                            raise InvalidUrlRedirectClientError(\n                                parsed_redirect_url,\n                                \"Invalid redirect URL origin\",\n                            ) from origin_val_err\n\n                        if (\n                            url.origin() != redirect_origin\n                            and not is_same_host_https_redirect\n                        ):\n                            auth = None\n                            headers.pop(hdrs.AUTHORIZATION, None)\n\n                        url = parsed_redirect_url\n                        params = {}\n                        resp.release()\n                        continue\n\n                    break\n\n            # check response status\n            if raise_for_status is None:\n                raise_for_status = self._raise_for_status\n\n            if raise_for_status is None:\n                pass\n            elif callable(raise_for_status):\n                await raise_for_status(resp)\n            elif raise_for_status:\n                resp.raise_for_status()\n\n            # register connection\n            if handle is not None:\n                if resp.connection is not None:\n                    resp.connection.add_callback(handle.cancel)\n                else:\n                    handle.cancel()\n\n            resp._history = tuple(history)\n\n            for trace in traces:\n                await trace.send_request_end(\n                    method, url.update_query(params), headers, resp\n                )\n            return resp\n\n        except BaseException as e:\n            # cleanup timer\n            tm.close()\n            if handle:\n                handle.cancel()\n                handle = None\n\n            for trace in traces:\n                await trace.send_request_exception(\n                    method, url.update_query(params), headers, e\n                )\n            raise\n\n    def ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> \"_WSRequestContextManager\":\n        \"\"\"Initiate websocket connection.\"\"\"\n        return _WSRequestContextManager(\n            self._ws_connect(\n                url,\n                method=method,\n                protocols=protocols,\n                timeout=timeout,\n                receive_timeout=receive_timeout,\n                autoclose=autoclose,\n                autoping=autoping,\n                heartbeat=heartbeat,\n                auth=auth,\n                origin=origin,\n                params=params,\n                headers=headers,\n                proxy=proxy,\n                proxy_auth=proxy_auth,\n                ssl=ssl,\n                server_hostname=server_hostname,\n                proxy_headers=proxy_headers,\n                compress=compress,\n                max_msg_size=max_msg_size,\n            )\n        )\n\n    async def _ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> ClientWebSocketResponse:\n        if timeout is sentinel or timeout is None:\n            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT\n        else:\n            if isinstance(timeout, ClientWSTimeout):\n                ws_timeout = timeout\n            else:\n                warnings.warn(\n                    \"parameter 'timeout' of type 'float' \"\n                    \"is deprecated, please use \"\n                    \"'timeout=ClientWSTimeout(ws_close=...)'\",\n                    DeprecationWarning,\n                    stacklevel=2,\n                )\n                ws_timeout = ClientWSTimeout(ws_close=timeout)\n\n        if receive_timeout is not None:\n            warnings.warn(\n                \"float parameter 'receive_timeout' \"\n                \"is deprecated, please use parameter \"\n                \"'timeout=ClientWSTimeout(ws_receive=...)'\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)\n\n        if headers is None:\n            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        default_headers = {\n            hdrs.UPGRADE: \"websocket\",\n            hdrs.CONNECTION: \"Upgrade\",\n            hdrs.SEC_WEBSOCKET_VERSION: \"13\",\n        }\n\n        for key, value in default_headers.items():\n            real_headers.setdefault(key, value)\n\n        sec_key = base64.b64encode(os.urandom(16))\n        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()\n\n        if protocols:\n            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = \",\".join(protocols)\n        if origin is not None:\n            real_headers[hdrs.ORIGIN] = origin\n        if compress:\n            extstr = ws_ext_gen(compress=compress)\n            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        # send request\n        resp = await self.request(\n            method,\n            url,\n            params=params,\n            headers=real_headers,\n            read_until_eof=False,\n            auth=auth,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            ssl=ssl,\n            server_hostname=server_hostname,\n            proxy_headers=proxy_headers,\n        )\n\n        try:\n            # check handshake\n            if resp.status != 101:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid response status\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.UPGRADE, \"\").lower() != \"websocket\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid upgrade header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.CONNECTION, \"\").lower() != \"upgrade\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid connection header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # key calculation\n            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, \"\")\n            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()\n            if r_key != match:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid challenge response\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # websocket protocol\n            protocol = None\n            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:\n                resp_protocols = [\n                    proto.strip()\n                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(\",\")\n                ]\n\n                for proto in resp_protocols:\n                    if proto in protocols:\n                        protocol = proto\n                        break\n\n            # websocket compress\n            notakeover = False\n            if compress:\n                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)\n                if compress_hdrs:\n                    try:\n                        compress, notakeover = ws_ext_parse(compress_hdrs)\n                    except WSHandshakeError as exc:\n                        raise WSServerHandshakeError(\n                            resp.request_info,\n                            resp.history,\n                            message=exc.args[0],\n                            status=resp.status,\n                            headers=resp.headers,\n                        ) from exc\n                else:\n                    compress = 0\n                    notakeover = False\n\n            conn = resp.connection\n            assert conn is not None\n            conn_proto = conn.protocol\n            assert conn_proto is not None\n\n            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater\n            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible\n            if ws_timeout.ws_receive is None:\n                # Reset regardless\n                conn_proto.read_timeout = None\n            elif conn_proto.read_timeout is not None:\n                conn_proto.read_timeout = max(\n                    ws_timeout.ws_receive, conn_proto.read_timeout\n                )\n\n            transport = conn.transport\n            assert transport is not None\n            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(\n                conn_proto, 2**16, loop=self._loop\n            )\n            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)\n            writer = WebSocketWriter(\n                conn_proto,\n                transport,\n                use_mask=True,\n                compress=compress,\n                notakeover=notakeover,\n            )\n        except BaseException:\n            resp.close()\n            raise\n        else:\n            return self._ws_response_class(\n                reader,\n                writer,\n                protocol,\n                resp,\n                ws_timeout,\n                autoclose,\n                autoping,\n                self._loop,\n                heartbeat=heartbeat,\n                compress=compress,\n                client_notakeover=notakeover,\n            )\n\n    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> \"CIMultiDict[str]\":\n        \"\"\"Add default headers and transform it to CIMultiDict\"\"\"\n        # Convert headers to MultiDict\n        result = CIMultiDict(self._default_headers)\n        if headers:\n            if not isinstance(headers, (MultiDictProxy, MultiDict)):\n                headers = CIMultiDict(headers)\n            added_names: Set[str] = set()\n            for key, value in headers.items():\n                if key in added_names:\n                    result.add(key, value)\n                else:\n                    result[key] = value\n                    added_names.add(key)\n        return result\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def get(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def options(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def head(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def post(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def put(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def patch(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def delete(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def get(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP GET request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def options(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP OPTIONS request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def head(\n            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP HEAD request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def post(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP POST request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_POST, url, data=data, **kwargs)\n            )\n\n        def put(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PUT request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PUT, url, data=data, **kwargs)\n            )\n\n        def patch(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PATCH request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)\n            )\n\n        def delete(self, url: StrOrURL, **kwargs: Any) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP DELETE request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_DELETE, url, **kwargs)\n            )\n\n    async def close(self) -> None:\n        \"\"\"Close underlying connector.\n\n        Release all acquired resources.\n        \"\"\"\n        if not self.closed:\n            if self._connector is not None and self._connector_owner:\n                await self._connector.close()\n            self._connector = None\n\n    @property\n    def closed(self) -> bool:\n        \"\"\"Is client session closed.\n\n        A readonly property.\n        \"\"\"\n        return self._connector is None or self._connector.closed\n\n    @property\n    def connector(self) -> Optional[BaseConnector]:\n        \"\"\"Connector instance used for the session.\"\"\"\n        return self._connector\n\n    @property\n    def cookie_jar(self) -> AbstractCookieJar:\n        \"\"\"The session cookies.\"\"\"\n        return self._cookie_jar\n\n    @property\n    def version(self) -> Tuple[int, int]:\n        \"\"\"The session HTTP protocol version.\"\"\"\n        return self._version\n\n    @property\n    def requote_redirect_url(self) -> bool:\n        \"\"\"Do URL requoting on redirection handling.\"\"\"\n        return self._requote_redirect_url\n\n    @property\n    def timeout(self) -> ClientTimeout:\n        \"\"\"Timeout for the session.\"\"\"\n        return self._timeout\n\n    @property\n    def headers(self) -> \"CIMultiDict[str]\":\n        \"\"\"The default headers of the client session.\"\"\"\n        return self._default_headers\n\n    @property\n    def skip_auto_headers(self) -> FrozenSet[istr]:\n        \"\"\"Headers for which autogeneration should be skipped\"\"\"\n        return self._skip_auto_headers\n\n    @property\n    def auth(self) -> Optional[BasicAuth]:\n        \"\"\"An object that represents HTTP Basic Authorization\"\"\"\n        return self._default_auth\n\n    @property\n    def json_serialize(self) -> JSONEncoder:\n        \"\"\"Json serializer callable\"\"\"\n        return self._json_serialize\n\n    @property\n    def connector_owner(self) -> bool:\n        \"\"\"Should connector be closed on session closing\"\"\"\n        return self._connector_owner\n\n    @property\n    def raise_for_status(\n        self,\n    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:\n        \"\"\"Should `ClientResponse.raise_for_status()` be called for each response.\"\"\"\n        return self._raise_for_status\n\n    @property\n    def auto_decompress(self) -> bool:\n        \"\"\"Should the body response be automatically decompressed.\"\"\"\n        return self._auto_decompress\n\n    @property\n    def trust_env(self) -> bool:\n        \"\"\"\n        Should proxies information from environment or netrc be trusted.\n\n        Information is from HTTP_PROXY / HTTPS_PROXY environment variables\n        or ~/.netrc file if present.\n        \"\"\"\n        return self._trust_env\n\n    @property\n    def trace_configs(self) -> List[TraceConfig[Any]]:\n        \"\"\"A list of TraceConfig instances used for client tracing\"\"\"\n        return self._trace_configs\n\n    def detach(self) -> None:\n        \"\"\"Detach connector from session without closing the former.\n\n        Session is switched to closed state anyway.\n        \"\"\"\n        self._connector = None\n\n    async def __aenter__(self) -> \"ClientSession\":\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        await self.close()\n\n\nclass _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]):\n    __slots__ = (\"_coro\", \"_resp\")\n\n    def __init__(self, coro: Coroutine[\"asyncio.Future[Any]\", None, _RetType]) -> None:\n        self._coro = coro\n\n    def send(self, arg: None) -> \"asyncio.Future[Any]\":\n        return self._coro.send(arg)\n\n    def throw(self, *args: Any, **kwargs: Any) -> \"asyncio.Future[Any]\":\n        return self._coro.throw(*args, **kwargs)\n\n    def close(self) -> None:\n        return self._coro.close()\n\n    def __await__(self) -> Generator[Any, None, _RetType]:\n        ret = self._coro.__await__()\n        return ret\n\n    def __iter__(self) -> Generator[Any, None, _RetType]:\n        return self.__await__()\n\n    async def __aenter__(self) -> _RetType:\n        self._resp = await self._coro\n        return self._resp\n\n\nclass _RequestContextManager(_BaseRequestContextManager[ClientResponse]):\n    __slots__ = ()\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        # We're basing behavior on the exception as it can be caused by\n        # user code unrelated to the status of the connection.  If you\n        # would like to close a connection you must do that\n        # explicitly.  Otherwise connection error handling should kick in\n        # and close/recycle the connection as required.\n        self._resp.release()\n        await self._resp.wait_for_close()\n\n\nclass _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]):\n    __slots__ = ()\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        await self._resp.close()\n\n\nclass _SessionRequestContextManager:\n    __slots__ = (\"_coro\", \"_resp\", \"_session\")\n\n    def __init__(\n        self,\n        coro: Coroutine[\"asyncio.Future[Any]\", None, ClientResponse],\n        session: ClientSession,\n    ) -> None:\n        self._coro = coro\n        self._resp: Optional[ClientResponse] = None\n        self._session = session\n\n    async def __aenter__(self) -> ClientResponse:\n        try:\n            self._resp = await self._coro\n        except BaseException:\n            await self._session.close()\n            raise\n        else:\n            return self._resp\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        assert self._resp is not None\n        self._resp.close()\n        await self._session.close()\n\n\ndef request(\n    method: str,\n    url: StrOrURL,\n    *,\n    params: Optional[Mapping[str, str]] = None,\n    data: Any = None,\n    json: Any = None,\n    headers: Optional[LooseHeaders] = None,\n    skip_auto_headers: Optional[Iterable[str]] = None,\n    auth: Optional[BasicAuth] = None,\n    allow_redirects: bool = True,\n    max_redirects: int = 10,\n    compress: Optional[str] = None,\n    chunked: Optional[bool] = None,\n    expect100: bool = False,\n    raise_for_status: Optional[bool] = None,\n    read_until_eof: bool = True,\n    proxy: Optional[StrOrURL] = None,\n    proxy_auth: Optional[BasicAuth] = None,\n    timeout: Union[ClientTimeout, _SENTINEL] = sentinel,\n    cookies: Optional[LooseCookies] = None,\n    version: HttpVersion = http.HttpVersion11,\n    connector: Optional[BaseConnector] = None,\n    read_bufsize: Optional[int] = None,\n    max_line_size: int = 8190,\n    max_field_size: int = 8190,\n) -> _SessionRequestContextManager:\n    \"\"\"Constructs and sends a request.\n\n    Returns response object.\n    method - HTTP method\n    url - request url\n    params - (optional) Dictionary or bytes to be sent in the query\n      string of the new request\n    data - (optional) Dictionary, bytes, or file-like object to\n      send in the body of the request\n    json - (optional) Any json compatible python object\n    headers - (optional) Dictionary of HTTP Headers to send with\n      the request\n    cookies - (optional) Dict object to send with the request\n    auth - (optional) BasicAuth named tuple represent HTTP Basic Auth\n    auth - aiohttp.helpers.BasicAuth\n    allow_redirects - (optional) If set to False, do not follow\n      redirects\n    version - Request HTTP version.\n    compress - Set to True if request has to be compressed\n       with deflate encoding.\n    chunked - Set to chunk size for chunked transfer encoding.\n    expect100 - Expect 100-continue response from server.\n    connector - BaseConnector sub-class instance to support\n       connection pooling.\n    read_until_eof - Read response until eof if response\n       does not have Content-Length header.\n    loop - Optional event loop.\n    timeout - Optional ClientTimeout settings structure, 5min\n       total timeout by default.\n    Usage::\n      >>> import aiohttp\n      >>> async with aiohttp.request('GET', 'http://python.org/') as resp:\n      ...    print(resp)\n      ...    data = await resp.read()\n      <ClientResponse(https://www.python.org/) [200 OK]>\n    \"\"\"\n    connector_owner = False\n    if connector is None:\n        connector_owner = True\n        connector = TCPConnector(force_close=True)\n\n    session = ClientSession(\n        cookies=cookies,\n        version=version,\n        timeout=timeout,\n        connector=connector,\n        connector_owner=connector_owner,\n    )\n\n    return _SessionRequestContextManager(\n        session._request(\n            method,\n            url,\n            params=params,\n            data=data,\n            json=json,\n            headers=headers,\n            skip_auto_headers=skip_auto_headers,\n            auth=auth,\n            allow_redirects=allow_redirects,\n            max_redirects=max_redirects,\n            compress=compress,\n            chunked=chunked,\n            expect100=expect100,\n            raise_for_status=raise_for_status,\n            read_until_eof=read_until_eof,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            read_bufsize=read_bufsize,\n            max_line_size=max_line_size,\n            max_field_size=max_field_size,\n        ),\n        session,\n    )\n",
            "header": {
                "file": {
                    "path": "aiohttp/client.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "e3e9b29d",
                "new_commit_hash": "4e2faa1a",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/aiohttp/client.py"
            },
            "plus_file": {
                "path": "b/aiohttp/client.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 543,
                            "length": 7
                        },
                        "new_range": {
                            "start": 543,
                            "length": 10
                        },
                        "section": "class ClientSession:"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "                    if auth is None:",
                                "type": "context"
                            },
                            {
                                "content": "                        auth = auth_from_url",
                                "type": "context"
                            },
                            {
                                "content": "                    if auth is None:",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "                    if auth is None and (",
                                "type": "added"
                            },
                            {
                                "content": "                        not self._base_url or self._base_url.origin() == url.origin()",
                                "type": "added"
                            },
                            {
                                "content": "                    ):",
                                "type": "added"
                            },
                            {
                                "content": "                        auth = self._default_auth",
                                "type": "context"
                            },
                            {
                                "content": "                    # It would be confusing if we support explicit",
                                "type": "context"
                            },
                            {
                                "content": "                    # Authorization header with auth argument",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "aiohttp/client.py",
                            "type": "class",
                            "name": "ClientSession",
                            "content": "class ClientSession:\n    \"\"\"First-class interface for making HTTP requests.\"\"\"\n\n    __slots__ = (\n        \"_base_url\",\n        \"_source_traceback\",\n        \"_connector\",\n        \"_loop\",\n        \"_cookie_jar\",\n        \"_connector_owner\",\n        \"_default_auth\",\n        \"_version\",\n        \"_json_serialize\",\n        \"_requote_redirect_url\",\n        \"_timeout\",\n        \"_raise_for_status\",\n        \"_auto_decompress\",\n        \"_trust_env\",\n        \"_default_headers\",\n        \"_skip_auto_headers\",\n        \"_request_class\",\n        \"_response_class\",\n        \"_ws_response_class\",\n        \"_trace_configs\",\n        \"_read_bufsize\",\n        \"_max_line_size\",\n        \"_max_field_size\",\n        \"_resolve_charset\",\n    )\n\n    def __init__(\n        self,\n        base_url: Optional[StrOrURL] = None,\n        *,\n        connector: Optional[BaseConnector] = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        json_serialize: JSONEncoder = json.dumps,\n        request_class: Type[ClientRequest] = ClientRequest,\n        response_class: Type[ClientResponse] = ClientResponse,\n        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,\n        version: HttpVersion = http.HttpVersion11,\n        cookie_jar: Optional[AbstractCookieJar] = None,\n        connector_owner: bool = True,\n        raise_for_status: Union[\n            bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = False,\n        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,\n        auto_decompress: bool = True,\n        trust_env: bool = False,\n        requote_redirect_url: bool = True,\n        trace_configs: Optional[List[TraceConfig[object]]] = None,\n        read_bufsize: int = 2**16,\n        max_line_size: int = 8190,\n        max_field_size: int = 8190,\n        fallback_charset_resolver: _CharsetResolver = lambda r, b: \"utf-8\",\n    ) -> None:\n        # We initialise _connector to None immediately, as it's referenced in __del__()\n        # and could cause issues if an exception occurs during initialisation.\n        self._connector: Optional[BaseConnector] = None\n        if base_url is None or isinstance(base_url, URL):\n            self._base_url: Optional[URL] = base_url\n        else:\n            self._base_url = URL(base_url)\n            assert (\n                self._base_url.origin() == self._base_url\n            ), \"Only absolute URLs without path part are supported\"\n\n        loop = asyncio.get_running_loop()\n\n        if timeout is sentinel or timeout is None:\n            timeout = DEFAULT_TIMEOUT\n        if not isinstance(timeout, ClientTimeout):\n            raise ValueError(\n                f\"timeout parameter cannot be of {type(timeout)} type, \"\n                \"please use 'timeout=ClientTimeout(...)'\",\n            )\n        self._timeout = timeout\n\n        if connector is None:\n            connector = TCPConnector()\n        # Initialize these three attrs before raising any exception,\n        # they are used in __del__\n        self._connector = connector\n        self._loop = loop\n        if loop.get_debug():\n            self._source_traceback: Optional[traceback.StackSummary] = (\n                traceback.extract_stack(sys._getframe(1))\n            )\n        else:\n            self._source_traceback = None\n\n        if connector._loop is not loop:\n            raise RuntimeError(\"Session and connector have to use same event loop\")\n\n        if cookie_jar is None:\n            cookie_jar = CookieJar()\n        self._cookie_jar = cookie_jar\n\n        if cookies is not None:\n            self._cookie_jar.update_cookies(cookies)\n\n        self._connector_owner = connector_owner\n        self._default_auth = auth\n        self._version = version\n        self._json_serialize = json_serialize\n        self._raise_for_status = raise_for_status\n        self._auto_decompress = auto_decompress\n        self._trust_env = trust_env\n        self._requote_redirect_url = requote_redirect_url\n        self._read_bufsize = read_bufsize\n        self._max_line_size = max_line_size\n        self._max_field_size = max_field_size\n\n        # Convert to list of tuples\n        if headers:\n            real_headers: CIMultiDict[str] = CIMultiDict(headers)\n        else:\n            real_headers = CIMultiDict()\n        self._default_headers: CIMultiDict[str] = real_headers\n        if skip_auto_headers is not None:\n            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)\n        else:\n            self._skip_auto_headers = frozenset()\n\n        self._request_class = request_class\n        self._response_class = response_class\n        self._ws_response_class = ws_response_class\n\n        self._trace_configs = trace_configs or []\n        for trace_config in self._trace_configs:\n            trace_config.freeze()\n\n        self._resolve_charset = fallback_charset_resolver\n\n    def __init_subclass__(cls: Type[\"ClientSession\"]) -> None:\n        raise TypeError(\n            \"Inheritance class {} from ClientSession \"\n            \"is forbidden\".format(cls.__name__)\n        )\n\n    def __del__(self, _warnings: Any = warnings) -> None:\n        if not self.closed:\n            _warnings.warn(\n                f\"Unclosed client session {self!r}\",\n                ResourceWarning,\n                source=self,\n            )\n            context = {\"client_session\": self, \"message\": \"Unclosed client session\"}\n            if self._source_traceback is not None:\n                context[\"source_traceback\"] = self._source_traceback\n            self._loop.call_exception_handler(context)\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def request(\n            self,\n            method: str,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def request(\n            self, method: str, url: StrOrURL, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP request.\"\"\"\n            return _RequestContextManager(self._request(method, url, **kwargs))\n\n    def _build_url(self, str_or_url: StrOrURL) -> URL:\n        url = URL(str_or_url)\n        if self._base_url is None:\n            return url\n        else:\n            assert not url.is_absolute() and url.path.startswith(\"/\")\n            return self._base_url.join(url)\n\n    async def _request(\n        self,\n        method: str,\n        str_or_url: StrOrURL,\n        *,\n        params: Optional[Mapping[str, str]] = None,\n        data: Any = None,\n        json: Any = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        allow_redirects: bool = True,\n        max_redirects: int = 10,\n        compress: Optional[str] = None,\n        chunked: Optional[bool] = None,\n        expect100: bool = False,\n        raise_for_status: Union[\n            None, bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = None,\n        read_until_eof: bool = True,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        trace_request_ctx: Optional[Mapping[str, str]] = None,\n        read_bufsize: Optional[int] = None,\n        auto_decompress: Optional[bool] = None,\n        max_line_size: Optional[int] = None,\n        max_field_size: Optional[int] = None,\n    ) -> ClientResponse:\n        # NOTE: timeout clamps existing connect and read timeouts.  We cannot\n        # set the default to None because we need to detect if the user wants\n        # to use the existing timeouts by setting timeout to None.\n\n        if self.closed:\n            raise RuntimeError(\"Session is closed\")\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        if data is not None and json is not None:\n            raise ValueError(\n                \"data and json parameters can not be used at the same time\"\n            )\n        elif json is not None:\n            data = payload.JsonPayload(json, dumps=self._json_serialize)\n\n        redirects = 0\n        history = []\n        version = self._version\n        params = params or {}\n\n        # Merge with default headers and transform to CIMultiDict\n        headers = self._prepare_headers(headers)\n        proxy_headers = self._prepare_headers(proxy_headers)\n\n        try:\n            url = self._build_url(str_or_url)\n        except ValueError as e:\n            raise InvalidUrlClientError(str_or_url) from e\n\n        assert self._connector is not None\n        if url.scheme not in self._connector.allowed_protocol_schema_set:\n            raise NonHttpUrlClientError(url)\n\n        skip_headers = set(self._skip_auto_headers)\n        if skip_auto_headers is not None:\n            for i in skip_auto_headers:\n                skip_headers.add(istr(i))\n\n        if proxy is not None:\n            try:\n                proxy = URL(proxy)\n            except ValueError as e:\n                raise InvalidURL(proxy) from e\n\n        if timeout is sentinel or timeout is None:\n            real_timeout: ClientTimeout = self._timeout\n        else:\n            real_timeout = timeout\n        # timeout is cumulative for all request operations\n        # (request, redirects, responses, data consuming)\n        tm = TimeoutHandle(\n            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold\n        )\n        handle = tm.start()\n\n        if read_bufsize is None:\n            read_bufsize = self._read_bufsize\n\n        if auto_decompress is None:\n            auto_decompress = self._auto_decompress\n\n        if max_line_size is None:\n            max_line_size = self._max_line_size\n\n        if max_field_size is None:\n            max_field_size = self._max_field_size\n\n        traces = [\n            Trace(\n                self,\n                trace_config,\n                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),\n            )\n            for trace_config in self._trace_configs\n        ]\n\n        for trace in traces:\n            await trace.send_request_start(method, url.update_query(params), headers)\n\n        timer = tm.timer()\n        try:\n            with timer:\n                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests\n                retry_persistent_connection = method in IDEMPOTENT_METHODS\n                while True:\n                    url, auth_from_url = strip_auth_from_url(url)\n                    if not url.raw_host:\n                        # NOTE: Bail early, otherwise, causes `InvalidURL` through\n                        # NOTE: `self._request_class()` below.\n                        err_exc_cls = (\n                            InvalidUrlRedirectClientError\n                            if redirects\n                            else InvalidUrlClientError\n                        )\n                        raise err_exc_cls(url)\n                    if auth and auth_from_url:\n                        raise ValueError(\n                            \"Cannot combine AUTH argument with \"\n                            \"credentials encoded in URL\"\n                        )\n\n                    if auth is None:\n                        auth = auth_from_url\n                    if auth is None:\n                        auth = self._default_auth\n                    # It would be confusing if we support explicit\n                    # Authorization header with auth argument\n                    if auth is not None and hdrs.AUTHORIZATION in headers:\n                        raise ValueError(\n                            \"Cannot combine AUTHORIZATION header \"\n                            \"with AUTH argument or credentials \"\n                            \"encoded in URL\"\n                        )\n\n                    all_cookies = self._cookie_jar.filter_cookies(url)\n\n                    if cookies is not None:\n                        tmp_cookie_jar = CookieJar()\n                        tmp_cookie_jar.update_cookies(cookies)\n                        req_cookies = tmp_cookie_jar.filter_cookies(url)\n                        if req_cookies:\n                            all_cookies.load(req_cookies)\n\n                    if proxy is not None:\n                        proxy = URL(proxy)\n                    elif self._trust_env:\n                        with suppress(LookupError):\n                            proxy, proxy_auth = get_env_proxy_for_url(url)\n\n                    req = self._request_class(\n                        method,\n                        url,\n                        params=params,\n                        headers=headers,\n                        skip_auto_headers=skip_headers if skip_headers else None,\n                        data=data,\n                        cookies=all_cookies,\n                        auth=auth,\n                        version=version,\n                        compress=compress,\n                        chunked=chunked,\n                        expect100=expect100,\n                        loop=self._loop,\n                        response_class=self._response_class,\n                        proxy=proxy,\n                        proxy_auth=proxy_auth,\n                        timer=timer,\n                        session=self,\n                        ssl=ssl,\n                        server_hostname=server_hostname,\n                        proxy_headers=proxy_headers,\n                        traces=traces,\n                        trust_env=self.trust_env,\n                    )\n\n                    # connection timeout\n                    try:\n                        async with ceil_timeout(\n                            real_timeout.connect,\n                            ceil_threshold=real_timeout.ceil_threshold,\n                        ):\n                            conn = await self._connector.connect(\n                                req, traces=traces, timeout=real_timeout\n                            )\n                    except asyncio.TimeoutError as exc:\n                        raise ConnectionTimeoutError(\n                            f\"Connection timeout to host {url}\"\n                        ) from exc\n\n                    assert conn.transport is not None\n\n                    assert conn.protocol is not None\n                    conn.protocol.set_response_params(\n                        timer=timer,\n                        skip_payload=method_must_be_empty_body(method),\n                        read_until_eof=read_until_eof,\n                        auto_decompress=auto_decompress,\n                        read_timeout=real_timeout.sock_read,\n                        read_bufsize=read_bufsize,\n                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,\n                        max_line_size=max_line_size,\n                        max_field_size=max_field_size,\n                    )\n\n                    try:\n                        try:\n                            resp = await req.send(conn)\n                            try:\n                                await resp.start(conn)\n                            except BaseException:\n                                resp.close()\n                                raise\n                        except BaseException:\n                            conn.close()\n                            raise\n                    except (ClientOSError, ServerDisconnectedError):\n                        if retry_persistent_connection:\n                            retry_persistent_connection = False\n                            continue\n                        raise\n                    except ClientError:\n                        raise\n                    except OSError as exc:\n                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                            raise\n                        raise ClientOSError(*exc.args) from exc\n\n                    self._cookie_jar.update_cookies(resp.cookies, resp.url)\n\n                    # redirects\n                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:\n                        for trace in traces:\n                            await trace.send_request_redirect(\n                                method, url.update_query(params), headers, resp\n                            )\n\n                        redirects += 1\n                        history.append(resp)\n                        if max_redirects and redirects >= max_redirects:\n                            resp.close()\n                            raise TooManyRedirects(\n                                history[0].request_info, tuple(history)\n                            )\n\n                        # For 301 and 302, mimic IE, now changed in RFC\n                        # https://github.com/kennethreitz/requests/pull/269\n                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (\n                            resp.status in (301, 302) and resp.method == hdrs.METH_POST\n                        ):\n                            method = hdrs.METH_GET\n                            data = None\n                            if headers.get(hdrs.CONTENT_LENGTH):\n                                headers.pop(hdrs.CONTENT_LENGTH)\n\n                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(\n                            hdrs.URI\n                        )\n                        if r_url is None:\n                            # see github.com/aio-libs/aiohttp/issues/2022\n                            break\n                        else:\n                            # reading from correct redirection\n                            # response is forbidden\n                            resp.release()\n\n                        try:\n                            parsed_redirect_url = URL(\n                                r_url, encoded=not self._requote_redirect_url\n                            )\n                        except ValueError as e:\n                            raise InvalidUrlRedirectClientError(\n                                r_url,\n                                \"Server attempted redirecting to a location that does not look like a URL\",\n                            ) from e\n\n                        scheme = parsed_redirect_url.scheme\n                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:\n                            resp.close()\n                            raise NonHttpUrlRedirectClientError(r_url)\n                        elif not scheme:\n                            parsed_redirect_url = url.join(parsed_redirect_url)\n\n                        is_same_host_https_redirect = (\n                            url.host == parsed_redirect_url.host\n                            and parsed_redirect_url.scheme == \"https\"\n                            and url.scheme == \"http\"\n                        )\n\n                        try:\n                            redirect_origin = parsed_redirect_url.origin()\n                        except ValueError as origin_val_err:\n                            raise InvalidUrlRedirectClientError(\n                                parsed_redirect_url,\n                                \"Invalid redirect URL origin\",\n                            ) from origin_val_err\n\n                        if (\n                            url.origin() != redirect_origin\n                            and not is_same_host_https_redirect\n                        ):\n                            auth = None\n                            headers.pop(hdrs.AUTHORIZATION, None)\n\n                        url = parsed_redirect_url\n                        params = {}\n                        resp.release()\n                        continue\n\n                    break\n\n            # check response status\n            if raise_for_status is None:\n                raise_for_status = self._raise_for_status\n\n            if raise_for_status is None:\n                pass\n            elif callable(raise_for_status):\n                await raise_for_status(resp)\n            elif raise_for_status:\n                resp.raise_for_status()\n\n            # register connection\n            if handle is not None:\n                if resp.connection is not None:\n                    resp.connection.add_callback(handle.cancel)\n                else:\n                    handle.cancel()\n\n            resp._history = tuple(history)\n\n            for trace in traces:\n                await trace.send_request_end(\n                    method, url.update_query(params), headers, resp\n                )\n            return resp\n\n        except BaseException as e:\n            # cleanup timer\n            tm.close()\n            if handle:\n                handle.cancel()\n                handle = None\n\n            for trace in traces:\n                await trace.send_request_exception(\n                    method, url.update_query(params), headers, e\n                )\n            raise\n\n    def ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> \"_WSRequestContextManager\":\n        \"\"\"Initiate websocket connection.\"\"\"\n        return _WSRequestContextManager(\n            self._ws_connect(\n                url,\n                method=method,\n                protocols=protocols,\n                timeout=timeout,\n                receive_timeout=receive_timeout,\n                autoclose=autoclose,\n                autoping=autoping,\n                heartbeat=heartbeat,\n                auth=auth,\n                origin=origin,\n                params=params,\n                headers=headers,\n                proxy=proxy,\n                proxy_auth=proxy_auth,\n                ssl=ssl,\n                server_hostname=server_hostname,\n                proxy_headers=proxy_headers,\n                compress=compress,\n                max_msg_size=max_msg_size,\n            )\n        )\n\n    async def _ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> ClientWebSocketResponse:\n        if timeout is sentinel or timeout is None:\n            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT\n        else:\n            if isinstance(timeout, ClientWSTimeout):\n                ws_timeout = timeout\n            else:\n                warnings.warn(\n                    \"parameter 'timeout' of type 'float' \"\n                    \"is deprecated, please use \"\n                    \"'timeout=ClientWSTimeout(ws_close=...)'\",\n                    DeprecationWarning,\n                    stacklevel=2,\n                )\n                ws_timeout = ClientWSTimeout(ws_close=timeout)\n\n        if receive_timeout is not None:\n            warnings.warn(\n                \"float parameter 'receive_timeout' \"\n                \"is deprecated, please use parameter \"\n                \"'timeout=ClientWSTimeout(ws_receive=...)'\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)\n\n        if headers is None:\n            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        default_headers = {\n            hdrs.UPGRADE: \"websocket\",\n            hdrs.CONNECTION: \"Upgrade\",\n            hdrs.SEC_WEBSOCKET_VERSION: \"13\",\n        }\n\n        for key, value in default_headers.items():\n            real_headers.setdefault(key, value)\n\n        sec_key = base64.b64encode(os.urandom(16))\n        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()\n\n        if protocols:\n            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = \",\".join(protocols)\n        if origin is not None:\n            real_headers[hdrs.ORIGIN] = origin\n        if compress:\n            extstr = ws_ext_gen(compress=compress)\n            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        # send request\n        resp = await self.request(\n            method,\n            url,\n            params=params,\n            headers=real_headers,\n            read_until_eof=False,\n            auth=auth,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            ssl=ssl,\n            server_hostname=server_hostname,\n            proxy_headers=proxy_headers,\n        )\n\n        try:\n            # check handshake\n            if resp.status != 101:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid response status\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.UPGRADE, \"\").lower() != \"websocket\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid upgrade header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.CONNECTION, \"\").lower() != \"upgrade\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid connection header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # key calculation\n            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, \"\")\n            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()\n            if r_key != match:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid challenge response\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # websocket protocol\n            protocol = None\n            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:\n                resp_protocols = [\n                    proto.strip()\n                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(\",\")\n                ]\n\n                for proto in resp_protocols:\n                    if proto in protocols:\n                        protocol = proto\n                        break\n\n            # websocket compress\n            notakeover = False\n            if compress:\n                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)\n                if compress_hdrs:\n                    try:\n                        compress, notakeover = ws_ext_parse(compress_hdrs)\n                    except WSHandshakeError as exc:\n                        raise WSServerHandshakeError(\n                            resp.request_info,\n                            resp.history,\n                            message=exc.args[0],\n                            status=resp.status,\n                            headers=resp.headers,\n                        ) from exc\n                else:\n                    compress = 0\n                    notakeover = False\n\n            conn = resp.connection\n            assert conn is not None\n            conn_proto = conn.protocol\n            assert conn_proto is not None\n\n            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater\n            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible\n            if ws_timeout.ws_receive is None:\n                # Reset regardless\n                conn_proto.read_timeout = None\n            elif conn_proto.read_timeout is not None:\n                conn_proto.read_timeout = max(\n                    ws_timeout.ws_receive, conn_proto.read_timeout\n                )\n\n            transport = conn.transport\n            assert transport is not None\n            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(\n                conn_proto, 2**16, loop=self._loop\n            )\n            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)\n            writer = WebSocketWriter(\n                conn_proto,\n                transport,\n                use_mask=True,\n                compress=compress,\n                notakeover=notakeover,\n            )\n        except BaseException:\n            resp.close()\n            raise\n        else:\n            return self._ws_response_class(\n                reader,\n                writer,\n                protocol,\n                resp,\n                ws_timeout,\n                autoclose,\n                autoping,\n                self._loop,\n                heartbeat=heartbeat,\n                compress=compress,\n                client_notakeover=notakeover,\n            )\n\n    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> \"CIMultiDict[str]\":\n        \"\"\"Add default headers and transform it to CIMultiDict\"\"\"\n        # Convert headers to MultiDict\n        result = CIMultiDict(self._default_headers)\n        if headers:\n            if not isinstance(headers, (MultiDictProxy, MultiDict)):\n                headers = CIMultiDict(headers)\n            added_names: Set[str] = set()\n            for key, value in headers.items():\n                if key in added_names:\n                    result.add(key, value)\n                else:\n                    result[key] = value\n                    added_names.add(key)\n        return result\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def get(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def options(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def head(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def post(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def put(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def patch(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def delete(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def get(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP GET request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def options(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP OPTIONS request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def head(\n            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP HEAD request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def post(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP POST request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_POST, url, data=data, **kwargs)\n            )\n\n        def put(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PUT request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PUT, url, data=data, **kwargs)\n            )\n\n        def patch(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PATCH request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)\n            )\n\n        def delete(self, url: StrOrURL, **kwargs: Any) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP DELETE request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_DELETE, url, **kwargs)\n            )\n\n    async def close(self) -> None:\n        \"\"\"Close underlying connector.\n\n        Release all acquired resources.\n        \"\"\"\n        if not self.closed:\n            if self._connector is not None and self._connector_owner:\n                await self._connector.close()\n            self._connector = None\n\n    @property\n    def closed(self) -> bool:\n        \"\"\"Is client session closed.\n\n        A readonly property.\n        \"\"\"\n        return self._connector is None or self._connector.closed\n\n    @property\n    def connector(self) -> Optional[BaseConnector]:\n        \"\"\"Connector instance used for the session.\"\"\"\n        return self._connector\n\n    @property\n    def cookie_jar(self) -> AbstractCookieJar:\n        \"\"\"The session cookies.\"\"\"\n        return self._cookie_jar\n\n    @property\n    def version(self) -> Tuple[int, int]:\n        \"\"\"The session HTTP protocol version.\"\"\"\n        return self._version\n\n    @property\n    def requote_redirect_url(self) -> bool:\n        \"\"\"Do URL requoting on redirection handling.\"\"\"\n        return self._requote_redirect_url\n\n    @property\n    def timeout(self) -> ClientTimeout:\n        \"\"\"Timeout for the session.\"\"\"\n        return self._timeout\n\n    @property\n    def headers(self) -> \"CIMultiDict[str]\":\n        \"\"\"The default headers of the client session.\"\"\"\n        return self._default_headers\n\n    @property\n    def skip_auto_headers(self) -> FrozenSet[istr]:\n        \"\"\"Headers for which autogeneration should be skipped\"\"\"\n        return self._skip_auto_headers\n\n    @property\n    def auth(self) -> Optional[BasicAuth]:\n        \"\"\"An object that represents HTTP Basic Authorization\"\"\"\n        return self._default_auth\n\n    @property\n    def json_serialize(self) -> JSONEncoder:\n        \"\"\"Json serializer callable\"\"\"\n        return self._json_serialize\n\n    @property\n    def connector_owner(self) -> bool:\n        \"\"\"Should connector be closed on session closing\"\"\"\n        return self._connector_owner\n\n    @property\n    def raise_for_status(\n        self,\n    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:\n        \"\"\"Should `ClientResponse.raise_for_status()` be called for each response.\"\"\"\n        return self._raise_for_status\n\n    @property\n    def auto_decompress(self) -> bool:\n        \"\"\"Should the body response be automatically decompressed.\"\"\"\n        return self._auto_decompress\n\n    @property\n    def trust_env(self) -> bool:\n        \"\"\"\n        Should proxies information from environment or netrc be trusted.\n\n        Information is from HTTP_PROXY / HTTPS_PROXY environment variables\n        or ~/.netrc file if present.\n        \"\"\"\n        return self._trust_env\n\n    @property\n    def trace_configs(self) -> List[TraceConfig[Any]]:\n        \"\"\"A list of TraceConfig instances used for client tracing\"\"\"\n        return self._trace_configs\n\n    def detach(self) -> None:\n        \"\"\"Detach connector from session without closing the former.\n\n        Session is switched to closed state anyway.\n        \"\"\"\n        self._connector = None\n\n    async def __aenter__(self) -> \"ClientSession\":\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        await self.close()",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 225,
                            "end_lineno": 1266,
                            "parent": null
                        },
                        {
                            "file_name": "aiohttp/client.py",
                            "type": "method",
                            "name": "ClientSession._request",
                            "content": "class ClientSession:\n    \"\"\"First-class interface for making HTTP requests.\"\"\"\n\n    __slots__ = (\n        \"_base_url\",\n        \"_source_traceback\",\n        \"_connector\",\n        \"_loop\",\n        \"_cookie_jar\",\n        \"_connector_owner\",\n        \"_default_auth\",\n        \"_version\",\n        \"_json_serialize\",\n        \"_requote_redirect_url\",\n        \"_timeout\",\n        \"_raise_for_status\",\n        \"_auto_decompress\",\n        \"_trust_env\",\n        \"_default_headers\",\n        \"_skip_auto_headers\",\n        \"_request_class\",\n        \"_response_class\",\n        \"_ws_response_class\",\n        \"_trace_configs\",\n        \"_read_bufsize\",\n        \"_max_line_size\",\n        \"_max_field_size\",\n        \"_resolve_charset\",\n    )\n\n    def __init__(\n        self,\n        base_url: Optional[StrOrURL] = None,\n        *,\n        connector: Optional[BaseConnector] = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        json_serialize: JSONEncoder = json.dumps,\n        request_class: Type[ClientRequest] = ClientRequest,\n        response_class: Type[ClientResponse] = ClientResponse,\n        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,\n        version: HttpVersion = http.HttpVersion11,\n        cookie_jar: Optional[AbstractCookieJar] = None,\n        connector_owner: bool = True,\n        raise_for_status: Union[\n            bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = False,\n        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,\n        auto_decompress: bool = True,\n        trust_env: bool = False,\n        requote_redirect_url: bool = True,\n        trace_configs: Optional[List[TraceConfig[object]]] = None,\n        read_bufsize: int = 2**16,\n        max_line_size: int = 8190,\n        max_field_size: int = 8190,\n        fallback_charset_resolver: _CharsetResolver = lambda r, b: \"utf-8\",\n    ) -> None:\n        # We initialise _connector to None immediately, as it's referenced in __del__()\n        # and could cause issues if an exception occurs during initialisation.\n        self._connector: Optional[BaseConnector] = None\n        if base_url is None or isinstance(base_url, URL):\n            self._base_url: Optional[URL] = base_url\n        else:\n            self._base_url = URL(base_url)\n            assert (\n                self._base_url.origin() == self._base_url\n            ), \"Only absolute URLs without path part are supported\"\n\n        loop = asyncio.get_running_loop()\n\n        if timeout is sentinel or timeout is None:\n            timeout = DEFAULT_TIMEOUT\n        if not isinstance(timeout, ClientTimeout):\n            raise ValueError(\n                f\"timeout parameter cannot be of {type(timeout)} type, \"\n                \"please use 'timeout=ClientTimeout(...)'\",\n            )\n        self._timeout = timeout\n\n        if connector is None:\n            connector = TCPConnector()\n        # Initialize these three attrs before raising any exception,\n        # they are used in __del__\n        self._connector = connector\n        self._loop = loop\n        if loop.get_debug():\n            self._source_traceback: Optional[traceback.StackSummary] = (\n                traceback.extract_stack(sys._getframe(1))\n            )\n        else:\n            self._source_traceback = None\n\n        if connector._loop is not loop:\n            raise RuntimeError(\"Session and connector have to use same event loop\")\n\n        if cookie_jar is None:\n            cookie_jar = CookieJar()\n        self._cookie_jar = cookie_jar\n\n        if cookies is not None:\n            self._cookie_jar.update_cookies(cookies)\n\n        self._connector_owner = connector_owner\n        self._default_auth = auth\n        self._version = version\n        self._json_serialize = json_serialize\n        self._raise_for_status = raise_for_status\n        self._auto_decompress = auto_decompress\n        self._trust_env = trust_env\n        self._requote_redirect_url = requote_redirect_url\n        self._read_bufsize = read_bufsize\n        self._max_line_size = max_line_size\n        self._max_field_size = max_field_size\n\n        # Convert to list of tuples\n        if headers:\n            real_headers: CIMultiDict[str] = CIMultiDict(headers)\n        else:\n            real_headers = CIMultiDict()\n        self._default_headers: CIMultiDict[str] = real_headers\n        if skip_auto_headers is not None:\n            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)\n        else:\n            self._skip_auto_headers = frozenset()\n\n        self._request_class = request_class\n        self._response_class = response_class\n        self._ws_response_class = ws_response_class\n\n        self._trace_configs = trace_configs or []\n        for trace_config in self._trace_configs:\n            trace_config.freeze()\n\n        self._resolve_charset = fallback_charset_resolver\n\n    def __init_subclass__(cls: Type[\"ClientSession\"]) -> None:\n        raise TypeError(\n            \"Inheritance class {} from ClientSession \"\n            \"is forbidden\".format(cls.__name__)\n        )\n\n    def __del__(self, _warnings: Any = warnings) -> None:\n        if not self.closed:\n            _warnings.warn(\n                f\"Unclosed client session {self!r}\",\n                ResourceWarning,\n                source=self,\n            )\n            context = {\"client_session\": self, \"message\": \"Unclosed client session\"}\n            if self._source_traceback is not None:\n                context[\"source_traceback\"] = self._source_traceback\n            self._loop.call_exception_handler(context)\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def request(\n            self,\n            method: str,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def request(\n            self, method: str, url: StrOrURL, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP request.\"\"\"\n            return _RequestContextManager(self._request(method, url, **kwargs))\n\n    def _build_url(self, str_or_url: StrOrURL) -> URL:\n        url = URL(str_or_url)\n        if self._base_url is None:\n            return url\n        else:\n            assert not url.is_absolute() and url.path.startswith(\"/\")\n            return self._base_url.join(url)\n\n    async def _request(\n        self,\n        method: str,\n        str_or_url: StrOrURL,\n        *,\n        params: Optional[Mapping[str, str]] = None,\n        data: Any = None,\n        json: Any = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        allow_redirects: bool = True,\n        max_redirects: int = 10,\n        compress: Optional[str] = None,\n        chunked: Optional[bool] = None,\n        expect100: bool = False,\n        raise_for_status: Union[\n            None, bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = None,\n        read_until_eof: bool = True,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        trace_request_ctx: Optional[Mapping[str, str]] = None,\n        read_bufsize: Optional[int] = None,\n        auto_decompress: Optional[bool] = None,\n        max_line_size: Optional[int] = None,\n        max_field_size: Optional[int] = None,\n    ) -> ClientResponse:\n        # NOTE: timeout clamps existing connect and read timeouts.  We cannot\n        # set the default to None because we need to detect if the user wants\n        # to use the existing timeouts by setting timeout to None.\n\n        if self.closed:\n            raise RuntimeError(\"Session is closed\")\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        if data is not None and json is not None:\n            raise ValueError(\n                \"data and json parameters can not be used at the same time\"\n            )\n        elif json is not None:\n            data = payload.JsonPayload(json, dumps=self._json_serialize)\n\n        redirects = 0\n        history = []\n        version = self._version\n        params = params or {}\n\n        # Merge with default headers and transform to CIMultiDict\n        headers = self._prepare_headers(headers)\n        proxy_headers = self._prepare_headers(proxy_headers)\n\n        try:\n            url = self._build_url(str_or_url)\n        except ValueError as e:\n            raise InvalidUrlClientError(str_or_url) from e\n\n        assert self._connector is not None\n        if url.scheme not in self._connector.allowed_protocol_schema_set:\n            raise NonHttpUrlClientError(url)\n\n        skip_headers = set(self._skip_auto_headers)\n        if skip_auto_headers is not None:\n            for i in skip_auto_headers:\n                skip_headers.add(istr(i))\n\n        if proxy is not None:\n            try:\n                proxy = URL(proxy)\n            except ValueError as e:\n                raise InvalidURL(proxy) from e\n\n        if timeout is sentinel or timeout is None:\n            real_timeout: ClientTimeout = self._timeout\n        else:\n            real_timeout = timeout\n        # timeout is cumulative for all request operations\n        # (request, redirects, responses, data consuming)\n        tm = TimeoutHandle(\n            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold\n        )\n        handle = tm.start()\n\n        if read_bufsize is None:\n            read_bufsize = self._read_bufsize\n\n        if auto_decompress is None:\n            auto_decompress = self._auto_decompress\n\n        if max_line_size is None:\n            max_line_size = self._max_line_size\n\n        if max_field_size is None:\n            max_field_size = self._max_field_size\n\n        traces = [\n            Trace(\n                self,\n                trace_config,\n                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),\n            )\n            for trace_config in self._trace_configs\n        ]\n\n        for trace in traces:\n            await trace.send_request_start(method, url.update_query(params), headers)\n\n        timer = tm.timer()\n        try:\n            with timer:\n                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests\n                retry_persistent_connection = method in IDEMPOTENT_METHODS\n                while True:\n                    url, auth_from_url = strip_auth_from_url(url)\n                    if not url.raw_host:\n                        # NOTE: Bail early, otherwise, causes `InvalidURL` through\n                        # NOTE: `self._request_class()` below.\n                        err_exc_cls = (\n                            InvalidUrlRedirectClientError\n                            if redirects\n                            else InvalidUrlClientError\n                        )\n                        raise err_exc_cls(url)\n                    if auth and auth_from_url:\n                        raise ValueError(\n                            \"Cannot combine AUTH argument with \"\n                            \"credentials encoded in URL\"\n                        )\n\n                    if auth is None:\n                        auth = auth_from_url\n                    if auth is None:\n                        auth = self._default_auth\n                    # It would be confusing if we support explicit\n                    # Authorization header with auth argument\n                    if auth is not None and hdrs.AUTHORIZATION in headers:\n                        raise ValueError(\n                            \"Cannot combine AUTHORIZATION header \"\n                            \"with AUTH argument or credentials \"\n                            \"encoded in URL\"\n                        )\n\n                    all_cookies = self._cookie_jar.filter_cookies(url)\n\n                    if cookies is not None:\n                        tmp_cookie_jar = CookieJar()\n                        tmp_cookie_jar.update_cookies(cookies)\n                        req_cookies = tmp_cookie_jar.filter_cookies(url)\n                        if req_cookies:\n                            all_cookies.load(req_cookies)\n\n                    if proxy is not None:\n                        proxy = URL(proxy)\n                    elif self._trust_env:\n                        with suppress(LookupError):\n                            proxy, proxy_auth = get_env_proxy_for_url(url)\n\n                    req = self._request_class(\n                        method,\n                        url,\n                        params=params,\n                        headers=headers,\n                        skip_auto_headers=skip_headers if skip_headers else None,\n                        data=data,\n                        cookies=all_cookies,\n                        auth=auth,\n                        version=version,\n                        compress=compress,\n                        chunked=chunked,\n                        expect100=expect100,\n                        loop=self._loop,\n                        response_class=self._response_class,\n                        proxy=proxy,\n                        proxy_auth=proxy_auth,\n                        timer=timer,\n                        session=self,\n                        ssl=ssl,\n                        server_hostname=server_hostname,\n                        proxy_headers=proxy_headers,\n                        traces=traces,\n                        trust_env=self.trust_env,\n                    )\n\n                    # connection timeout\n                    try:\n                        async with ceil_timeout(\n                            real_timeout.connect,\n                            ceil_threshold=real_timeout.ceil_threshold,\n                        ):\n                            conn = await self._connector.connect(\n                                req, traces=traces, timeout=real_timeout\n                            )\n                    except asyncio.TimeoutError as exc:\n                        raise ConnectionTimeoutError(\n                            f\"Connection timeout to host {url}\"\n                        ) from exc\n\n                    assert conn.transport is not None\n\n                    assert conn.protocol is not None\n                    conn.protocol.set_response_params(\n                        timer=timer,\n                        skip_payload=method_must_be_empty_body(method),\n                        read_until_eof=read_until_eof,\n                        auto_decompress=auto_decompress,\n                        read_timeout=real_timeout.sock_read,\n                        read_bufsize=read_bufsize,\n                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,\n                        max_line_size=max_line_size,\n                        max_field_size=max_field_size,\n                    )\n\n                    try:\n                        try:\n                            resp = await req.send(conn)\n                            try:\n                                await resp.start(conn)\n                            except BaseException:\n                                resp.close()\n                                raise\n                        except BaseException:\n                            conn.close()\n                            raise\n                    except (ClientOSError, ServerDisconnectedError):\n                        if retry_persistent_connection:\n                            retry_persistent_connection = False\n                            continue\n                        raise\n                    except ClientError:\n                        raise\n                    except OSError as exc:\n                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                            raise\n                        raise ClientOSError(*exc.args) from exc\n\n                    self._cookie_jar.update_cookies(resp.cookies, resp.url)\n\n                    # redirects\n                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:\n                        for trace in traces:\n                            await trace.send_request_redirect(\n                                method, url.update_query(params), headers, resp\n                            )\n\n                        redirects += 1\n                        history.append(resp)\n                        if max_redirects and redirects >= max_redirects:\n                            resp.close()\n                            raise TooManyRedirects(\n                                history[0].request_info, tuple(history)\n                            )\n\n                        # For 301 and 302, mimic IE, now changed in RFC\n                        # https://github.com/kennethreitz/requests/pull/269\n                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (\n                            resp.status in (301, 302) and resp.method == hdrs.METH_POST\n                        ):\n                            method = hdrs.METH_GET\n                            data = None\n                            if headers.get(hdrs.CONTENT_LENGTH):\n                                headers.pop(hdrs.CONTENT_LENGTH)\n\n                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(\n                            hdrs.URI\n                        )\n                        if r_url is None:\n                            # see github.com/aio-libs/aiohttp/issues/2022\n                            break\n                        else:\n                            # reading from correct redirection\n                            # response is forbidden\n                            resp.release()\n\n                        try:\n                            parsed_redirect_url = URL(\n                                r_url, encoded=not self._requote_redirect_url\n                            )\n                        except ValueError as e:\n                            raise InvalidUrlRedirectClientError(\n                                r_url,\n                                \"Server attempted redirecting to a location that does not look like a URL\",\n                            ) from e\n\n                        scheme = parsed_redirect_url.scheme\n                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:\n                            resp.close()\n                            raise NonHttpUrlRedirectClientError(r_url)\n                        elif not scheme:\n                            parsed_redirect_url = url.join(parsed_redirect_url)\n\n                        is_same_host_https_redirect = (\n                            url.host == parsed_redirect_url.host\n                            and parsed_redirect_url.scheme == \"https\"\n                            and url.scheme == \"http\"\n                        )\n\n                        try:\n                            redirect_origin = parsed_redirect_url.origin()\n                        except ValueError as origin_val_err:\n                            raise InvalidUrlRedirectClientError(\n                                parsed_redirect_url,\n                                \"Invalid redirect URL origin\",\n                            ) from origin_val_err\n\n                        if (\n                            url.origin() != redirect_origin\n                            and not is_same_host_https_redirect\n                        ):\n                            auth = None\n                            headers.pop(hdrs.AUTHORIZATION, None)\n\n                        url = parsed_redirect_url\n                        params = {}\n                        resp.release()\n                        continue\n\n                    break\n\n            # check response status\n            if raise_for_status is None:\n                raise_for_status = self._raise_for_status\n\n            if raise_for_status is None:\n                pass\n            elif callable(raise_for_status):\n                await raise_for_status(resp)\n            elif raise_for_status:\n                resp.raise_for_status()\n\n            # register connection\n            if handle is not None:\n                if resp.connection is not None:\n                    resp.connection.add_callback(handle.cancel)\n                else:\n                    handle.cancel()\n\n            resp._history = tuple(history)\n\n            for trace in traces:\n                await trace.send_request_end(\n                    method, url.update_query(params), headers, resp\n                )\n            return resp\n\n        except BaseException as e:\n            # cleanup timer\n            tm.close()\n            if handle:\n                handle.cancel()\n                handle = None\n\n            for trace in traces:\n                await trace.send_request_exception(\n                    method, url.update_query(params), headers, e\n                )\n            raise\n\n    def ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> \"_WSRequestContextManager\":\n        \"\"\"Initiate websocket connection.\"\"\"\n        return _WSRequestContextManager(\n            self._ws_connect(\n                url,\n                method=method,\n                protocols=protocols,\n                timeout=timeout,\n                receive_timeout=receive_timeout,\n                autoclose=autoclose,\n                autoping=autoping,\n                heartbeat=heartbeat,\n                auth=auth,\n                origin=origin,\n                params=params,\n                headers=headers,\n                proxy=proxy,\n                proxy_auth=proxy_auth,\n                ssl=ssl,\n                server_hostname=server_hostname,\n                proxy_headers=proxy_headers,\n                compress=compress,\n                max_msg_size=max_msg_size,\n            )\n        )\n\n    async def _ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> ClientWebSocketResponse:\n        if timeout is sentinel or timeout is None:\n            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT\n        else:\n            if isinstance(timeout, ClientWSTimeout):\n                ws_timeout = timeout\n            else:\n                warnings.warn(\n                    \"parameter 'timeout' of type 'float' \"\n                    \"is deprecated, please use \"\n                    \"'timeout=ClientWSTimeout(ws_close=...)'\",\n                    DeprecationWarning,\n                    stacklevel=2,\n                )\n                ws_timeout = ClientWSTimeout(ws_close=timeout)\n\n        if receive_timeout is not None:\n            warnings.warn(\n                \"float parameter 'receive_timeout' \"\n                \"is deprecated, please use parameter \"\n                \"'timeout=ClientWSTimeout(ws_receive=...)'\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)\n\n        if headers is None:\n            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        default_headers = {\n            hdrs.UPGRADE: \"websocket\",\n            hdrs.CONNECTION: \"Upgrade\",\n            hdrs.SEC_WEBSOCKET_VERSION: \"13\",\n        }\n\n        for key, value in default_headers.items():\n            real_headers.setdefault(key, value)\n\n        sec_key = base64.b64encode(os.urandom(16))\n        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()\n\n        if protocols:\n            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = \",\".join(protocols)\n        if origin is not None:\n            real_headers[hdrs.ORIGIN] = origin\n        if compress:\n            extstr = ws_ext_gen(compress=compress)\n            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        # send request\n        resp = await self.request(\n            method,\n            url,\n            params=params,\n            headers=real_headers,\n            read_until_eof=False,\n            auth=auth,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            ssl=ssl,\n            server_hostname=server_hostname,\n            proxy_headers=proxy_headers,\n        )\n\n        try:\n            # check handshake\n            if resp.status != 101:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid response status\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.UPGRADE, \"\").lower() != \"websocket\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid upgrade header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.CONNECTION, \"\").lower() != \"upgrade\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid connection header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # key calculation\n            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, \"\")\n            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()\n            if r_key != match:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid challenge response\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # websocket protocol\n            protocol = None\n            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:\n                resp_protocols = [\n                    proto.strip()\n                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(\",\")\n                ]\n\n                for proto in resp_protocols:\n                    if proto in protocols:\n                        protocol = proto\n                        break\n\n            # websocket compress\n            notakeover = False\n            if compress:\n                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)\n                if compress_hdrs:\n                    try:\n                        compress, notakeover = ws_ext_parse(compress_hdrs)\n                    except WSHandshakeError as exc:\n                        raise WSServerHandshakeError(\n                            resp.request_info,\n                            resp.history,\n                            message=exc.args[0],\n                            status=resp.status,\n                            headers=resp.headers,\n                        ) from exc\n                else:\n                    compress = 0\n                    notakeover = False\n\n            conn = resp.connection\n            assert conn is not None\n            conn_proto = conn.protocol\n            assert conn_proto is not None\n\n            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater\n            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible\n            if ws_timeout.ws_receive is None:\n                # Reset regardless\n                conn_proto.read_timeout = None\n            elif conn_proto.read_timeout is not None:\n                conn_proto.read_timeout = max(\n                    ws_timeout.ws_receive, conn_proto.read_timeout\n                )\n\n            transport = conn.transport\n            assert transport is not None\n            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(\n                conn_proto, 2**16, loop=self._loop\n            )\n            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)\n            writer = WebSocketWriter(\n                conn_proto,\n                transport,\n                use_mask=True,\n                compress=compress,\n                notakeover=notakeover,\n            )\n        except BaseException:\n            resp.close()\n            raise\n        else:\n            return self._ws_response_class(\n                reader,\n                writer,\n                protocol,\n                resp,\n                ws_timeout,\n                autoclose,\n                autoping,\n                self._loop,\n                heartbeat=heartbeat,\n                compress=compress,\n                client_notakeover=notakeover,\n            )\n\n    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> \"CIMultiDict[str]\":\n        \"\"\"Add default headers and transform it to CIMultiDict\"\"\"\n        # Convert headers to MultiDict\n        result = CIMultiDict(self._default_headers)\n        if headers:\n            if not isinstance(headers, (MultiDictProxy, MultiDict)):\n                headers = CIMultiDict(headers)\n            added_names: Set[str] = set()\n            for key, value in headers.items():\n                if key in added_names:\n                    result.add(key, value)\n                else:\n                    result[key] = value\n                    added_names.add(key)\n        return result\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def get(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def options(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def head(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def post(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def put(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def patch(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def delete(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def get(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP GET request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def options(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP OPTIONS request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def head(\n            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP HEAD request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def post(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP POST request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_POST, url, data=data, **kwargs)\n            )\n\n        def put(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PUT request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PUT, url, data=data, **kwargs)\n            )\n\n        def patch(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PATCH request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)\n            )\n\n        def delete(self, url: StrOrURL, **kwargs: Any) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP DELETE request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_DELETE, url, **kwargs)\n            )\n\n    async def close(self) -> None:\n        \"\"\"Close underlying connector.\n\n        Release all acquired resources.\n        \"\"\"\n        if not self.closed:\n            if self._connector is not None and self._connector_owner:\n                await self._connector.close()\n            self._connector = None\n\n    @property\n    def closed(self) -> bool:\n        \"\"\"Is client session closed.\n\n        A readonly property.\n        \"\"\"\n        return self._connector is None or self._connector.closed\n\n    @property\n    def connector(self) -> Optional[BaseConnector]:\n        \"\"\"Connector instance used for the session.\"\"\"\n        return self._connector\n\n    @property\n    def cookie_jar(self) -> AbstractCookieJar:\n        \"\"\"The session cookies.\"\"\"\n        return self._cookie_jar\n\n    @property\n    def version(self) -> Tuple[int, int]:\n        \"\"\"The session HTTP protocol version.\"\"\"\n        return self._version\n\n    @property\n    def requote_redirect_url(self) -> bool:\n        \"\"\"Do URL requoting on redirection handling.\"\"\"\n        return self._requote_redirect_url\n\n    @property\n    def timeout(self) -> ClientTimeout:\n        \"\"\"Timeout for the session.\"\"\"\n        return self._timeout\n\n    @property\n    def headers(self) -> \"CIMultiDict[str]\":\n        \"\"\"The default headers of the client session.\"\"\"\n        return self._default_headers\n\n    @property\n    def skip_auto_headers(self) -> FrozenSet[istr]:\n        \"\"\"Headers for which autogeneration should be skipped\"\"\"\n        return self._skip_auto_headers\n\n    @property\n    def auth(self) -> Optional[BasicAuth]:\n        \"\"\"An object that represents HTTP Basic Authorization\"\"\"\n        return self._default_auth\n\n    @property\n    def json_serialize(self) -> JSONEncoder:\n        \"\"\"Json serializer callable\"\"\"\n        return self._json_serialize\n\n    @property\n    def connector_owner(self) -> bool:\n        \"\"\"Should connector be closed on session closing\"\"\"\n        return self._connector_owner\n\n    @property\n    def raise_for_status(\n        self,\n    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:\n        \"\"\"Should `ClientResponse.raise_for_status()` be called for each response.\"\"\"\n        return self._raise_for_status\n\n    @property\n    def auto_decompress(self) -> bool:\n        \"\"\"Should the body response be automatically decompressed.\"\"\"\n        return self._auto_decompress\n\n    @property\n    def trust_env(self) -> bool:\n        \"\"\"\n        Should proxies information from environment or netrc be trusted.\n\n        Information is from HTTP_PROXY / HTTPS_PROXY environment variables\n        or ~/.netrc file if present.\n        \"\"\"\n        return self._trust_env\n\n    @property\n    def trace_configs(self) -> List[TraceConfig[Any]]:\n        \"\"\"A list of TraceConfig instances used for client tracing\"\"\"\n        return self._trace_configs\n\n    def detach(self) -> None:\n        \"\"\"Detach connector from session without closing the former.\n\n        Session is switched to closed state anyway.\n        \"\"\"\n        self._connector = None\n\n    async def __aenter__(self) -> \"ClientSession\":\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        await self.close()",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 405,
                            "end_lineno": 770,
                            "parent": {
                                "file_name": "aiohttp/client.py",
                                "type": "class",
                                "name": "ClientSession",
                                "content": "class ClientSession:\n    \"\"\"First-class interface for making HTTP requests.\"\"\"\n\n    __slots__ = (\n        \"_base_url\",\n        \"_source_traceback\",\n        \"_connector\",\n        \"_loop\",\n        \"_cookie_jar\",\n        \"_connector_owner\",\n        \"_default_auth\",\n        \"_version\",\n        \"_json_serialize\",\n        \"_requote_redirect_url\",\n        \"_timeout\",\n        \"_raise_for_status\",\n        \"_auto_decompress\",\n        \"_trust_env\",\n        \"_default_headers\",\n        \"_skip_auto_headers\",\n        \"_request_class\",\n        \"_response_class\",\n        \"_ws_response_class\",\n        \"_trace_configs\",\n        \"_read_bufsize\",\n        \"_max_line_size\",\n        \"_max_field_size\",\n        \"_resolve_charset\",\n    )\n\n    def __init__(\n        self,\n        base_url: Optional[StrOrURL] = None,\n        *,\n        connector: Optional[BaseConnector] = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        json_serialize: JSONEncoder = json.dumps,\n        request_class: Type[ClientRequest] = ClientRequest,\n        response_class: Type[ClientResponse] = ClientResponse,\n        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,\n        version: HttpVersion = http.HttpVersion11,\n        cookie_jar: Optional[AbstractCookieJar] = None,\n        connector_owner: bool = True,\n        raise_for_status: Union[\n            bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = False,\n        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,\n        auto_decompress: bool = True,\n        trust_env: bool = False,\n        requote_redirect_url: bool = True,\n        trace_configs: Optional[List[TraceConfig[object]]] = None,\n        read_bufsize: int = 2**16,\n        max_line_size: int = 8190,\n        max_field_size: int = 8190,\n        fallback_charset_resolver: _CharsetResolver = lambda r, b: \"utf-8\",\n    ) -> None:\n        # We initialise _connector to None immediately, as it's referenced in __del__()\n        # and could cause issues if an exception occurs during initialisation.\n        self._connector: Optional[BaseConnector] = None\n        if base_url is None or isinstance(base_url, URL):\n            self._base_url: Optional[URL] = base_url\n        else:\n            self._base_url = URL(base_url)\n            assert (\n                self._base_url.origin() == self._base_url\n            ), \"Only absolute URLs without path part are supported\"\n\n        loop = asyncio.get_running_loop()\n\n        if timeout is sentinel or timeout is None:\n            timeout = DEFAULT_TIMEOUT\n        if not isinstance(timeout, ClientTimeout):\n            raise ValueError(\n                f\"timeout parameter cannot be of {type(timeout)} type, \"\n                \"please use 'timeout=ClientTimeout(...)'\",\n            )\n        self._timeout = timeout\n\n        if connector is None:\n            connector = TCPConnector()\n        # Initialize these three attrs before raising any exception,\n        # they are used in __del__\n        self._connector = connector\n        self._loop = loop\n        if loop.get_debug():\n            self._source_traceback: Optional[traceback.StackSummary] = (\n                traceback.extract_stack(sys._getframe(1))\n            )\n        else:\n            self._source_traceback = None\n\n        if connector._loop is not loop:\n            raise RuntimeError(\"Session and connector have to use same event loop\")\n\n        if cookie_jar is None:\n            cookie_jar = CookieJar()\n        self._cookie_jar = cookie_jar\n\n        if cookies is not None:\n            self._cookie_jar.update_cookies(cookies)\n\n        self._connector_owner = connector_owner\n        self._default_auth = auth\n        self._version = version\n        self._json_serialize = json_serialize\n        self._raise_for_status = raise_for_status\n        self._auto_decompress = auto_decompress\n        self._trust_env = trust_env\n        self._requote_redirect_url = requote_redirect_url\n        self._read_bufsize = read_bufsize\n        self._max_line_size = max_line_size\n        self._max_field_size = max_field_size\n\n        # Convert to list of tuples\n        if headers:\n            real_headers: CIMultiDict[str] = CIMultiDict(headers)\n        else:\n            real_headers = CIMultiDict()\n        self._default_headers: CIMultiDict[str] = real_headers\n        if skip_auto_headers is not None:\n            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)\n        else:\n            self._skip_auto_headers = frozenset()\n\n        self._request_class = request_class\n        self._response_class = response_class\n        self._ws_response_class = ws_response_class\n\n        self._trace_configs = trace_configs or []\n        for trace_config in self._trace_configs:\n            trace_config.freeze()\n\n        self._resolve_charset = fallback_charset_resolver\n\n    def __init_subclass__(cls: Type[\"ClientSession\"]) -> None:\n        raise TypeError(\n            \"Inheritance class {} from ClientSession \"\n            \"is forbidden\".format(cls.__name__)\n        )\n\n    def __del__(self, _warnings: Any = warnings) -> None:\n        if not self.closed:\n            _warnings.warn(\n                f\"Unclosed client session {self!r}\",\n                ResourceWarning,\n                source=self,\n            )\n            context = {\"client_session\": self, \"message\": \"Unclosed client session\"}\n            if self._source_traceback is not None:\n                context[\"source_traceback\"] = self._source_traceback\n            self._loop.call_exception_handler(context)\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def request(\n            self,\n            method: str,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def request(\n            self, method: str, url: StrOrURL, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP request.\"\"\"\n            return _RequestContextManager(self._request(method, url, **kwargs))\n\n    def _build_url(self, str_or_url: StrOrURL) -> URL:\n        url = URL(str_or_url)\n        if self._base_url is None:\n            return url\n        else:\n            assert not url.is_absolute() and url.path.startswith(\"/\")\n            return self._base_url.join(url)\n\n    async def _request(\n        self,\n        method: str,\n        str_or_url: StrOrURL,\n        *,\n        params: Optional[Mapping[str, str]] = None,\n        data: Any = None,\n        json: Any = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        allow_redirects: bool = True,\n        max_redirects: int = 10,\n        compress: Optional[str] = None,\n        chunked: Optional[bool] = None,\n        expect100: bool = False,\n        raise_for_status: Union[\n            None, bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = None,\n        read_until_eof: bool = True,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        trace_request_ctx: Optional[Mapping[str, str]] = None,\n        read_bufsize: Optional[int] = None,\n        auto_decompress: Optional[bool] = None,\n        max_line_size: Optional[int] = None,\n        max_field_size: Optional[int] = None,\n    ) -> ClientResponse:\n        # NOTE: timeout clamps existing connect and read timeouts.  We cannot\n        # set the default to None because we need to detect if the user wants\n        # to use the existing timeouts by setting timeout to None.\n\n        if self.closed:\n            raise RuntimeError(\"Session is closed\")\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        if data is not None and json is not None:\n            raise ValueError(\n                \"data and json parameters can not be used at the same time\"\n            )\n        elif json is not None:\n            data = payload.JsonPayload(json, dumps=self._json_serialize)\n\n        redirects = 0\n        history = []\n        version = self._version\n        params = params or {}\n\n        # Merge with default headers and transform to CIMultiDict\n        headers = self._prepare_headers(headers)\n        proxy_headers = self._prepare_headers(proxy_headers)\n\n        try:\n            url = self._build_url(str_or_url)\n        except ValueError as e:\n            raise InvalidUrlClientError(str_or_url) from e\n\n        assert self._connector is not None\n        if url.scheme not in self._connector.allowed_protocol_schema_set:\n            raise NonHttpUrlClientError(url)\n\n        skip_headers = set(self._skip_auto_headers)\n        if skip_auto_headers is not None:\n            for i in skip_auto_headers:\n                skip_headers.add(istr(i))\n\n        if proxy is not None:\n            try:\n                proxy = URL(proxy)\n            except ValueError as e:\n                raise InvalidURL(proxy) from e\n\n        if timeout is sentinel or timeout is None:\n            real_timeout: ClientTimeout = self._timeout\n        else:\n            real_timeout = timeout\n        # timeout is cumulative for all request operations\n        # (request, redirects, responses, data consuming)\n        tm = TimeoutHandle(\n            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold\n        )\n        handle = tm.start()\n\n        if read_bufsize is None:\n            read_bufsize = self._read_bufsize\n\n        if auto_decompress is None:\n            auto_decompress = self._auto_decompress\n\n        if max_line_size is None:\n            max_line_size = self._max_line_size\n\n        if max_field_size is None:\n            max_field_size = self._max_field_size\n\n        traces = [\n            Trace(\n                self,\n                trace_config,\n                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),\n            )\n            for trace_config in self._trace_configs\n        ]\n\n        for trace in traces:\n            await trace.send_request_start(method, url.update_query(params), headers)\n\n        timer = tm.timer()\n        try:\n            with timer:\n                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests\n                retry_persistent_connection = method in IDEMPOTENT_METHODS\n                while True:\n                    url, auth_from_url = strip_auth_from_url(url)\n                    if not url.raw_host:\n                        # NOTE: Bail early, otherwise, causes `InvalidURL` through\n                        # NOTE: `self._request_class()` below.\n                        err_exc_cls = (\n                            InvalidUrlRedirectClientError\n                            if redirects\n                            else InvalidUrlClientError\n                        )\n                        raise err_exc_cls(url)\n                    if auth and auth_from_url:\n                        raise ValueError(\n                            \"Cannot combine AUTH argument with \"\n                            \"credentials encoded in URL\"\n                        )\n\n                    if auth is None:\n                        auth = auth_from_url\n                    if auth is None:\n                        auth = self._default_auth\n                    # It would be confusing if we support explicit\n                    # Authorization header with auth argument\n                    if auth is not None and hdrs.AUTHORIZATION in headers:\n                        raise ValueError(\n                            \"Cannot combine AUTHORIZATION header \"\n                            \"with AUTH argument or credentials \"\n                            \"encoded in URL\"\n                        )\n\n                    all_cookies = self._cookie_jar.filter_cookies(url)\n\n                    if cookies is not None:\n                        tmp_cookie_jar = CookieJar()\n                        tmp_cookie_jar.update_cookies(cookies)\n                        req_cookies = tmp_cookie_jar.filter_cookies(url)\n                        if req_cookies:\n                            all_cookies.load(req_cookies)\n\n                    if proxy is not None:\n                        proxy = URL(proxy)\n                    elif self._trust_env:\n                        with suppress(LookupError):\n                            proxy, proxy_auth = get_env_proxy_for_url(url)\n\n                    req = self._request_class(\n                        method,\n                        url,\n                        params=params,\n                        headers=headers,\n                        skip_auto_headers=skip_headers if skip_headers else None,\n                        data=data,\n                        cookies=all_cookies,\n                        auth=auth,\n                        version=version,\n                        compress=compress,\n                        chunked=chunked,\n                        expect100=expect100,\n                        loop=self._loop,\n                        response_class=self._response_class,\n                        proxy=proxy,\n                        proxy_auth=proxy_auth,\n                        timer=timer,\n                        session=self,\n                        ssl=ssl,\n                        server_hostname=server_hostname,\n                        proxy_headers=proxy_headers,\n                        traces=traces,\n                        trust_env=self.trust_env,\n                    )\n\n                    # connection timeout\n                    try:\n                        async with ceil_timeout(\n                            real_timeout.connect,\n                            ceil_threshold=real_timeout.ceil_threshold,\n                        ):\n                            conn = await self._connector.connect(\n                                req, traces=traces, timeout=real_timeout\n                            )\n                    except asyncio.TimeoutError as exc:\n                        raise ConnectionTimeoutError(\n                            f\"Connection timeout to host {url}\"\n                        ) from exc\n\n                    assert conn.transport is not None\n\n                    assert conn.protocol is not None\n                    conn.protocol.set_response_params(\n                        timer=timer,\n                        skip_payload=method_must_be_empty_body(method),\n                        read_until_eof=read_until_eof,\n                        auto_decompress=auto_decompress,\n                        read_timeout=real_timeout.sock_read,\n                        read_bufsize=read_bufsize,\n                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,\n                        max_line_size=max_line_size,\n                        max_field_size=max_field_size,\n                    )\n\n                    try:\n                        try:\n                            resp = await req.send(conn)\n                            try:\n                                await resp.start(conn)\n                            except BaseException:\n                                resp.close()\n                                raise\n                        except BaseException:\n                            conn.close()\n                            raise\n                    except (ClientOSError, ServerDisconnectedError):\n                        if retry_persistent_connection:\n                            retry_persistent_connection = False\n                            continue\n                        raise\n                    except ClientError:\n                        raise\n                    except OSError as exc:\n                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                            raise\n                        raise ClientOSError(*exc.args) from exc\n\n                    self._cookie_jar.update_cookies(resp.cookies, resp.url)\n\n                    # redirects\n                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:\n                        for trace in traces:\n                            await trace.send_request_redirect(\n                                method, url.update_query(params), headers, resp\n                            )\n\n                        redirects += 1\n                        history.append(resp)\n                        if max_redirects and redirects >= max_redirects:\n                            resp.close()\n                            raise TooManyRedirects(\n                                history[0].request_info, tuple(history)\n                            )\n\n                        # For 301 and 302, mimic IE, now changed in RFC\n                        # https://github.com/kennethreitz/requests/pull/269\n                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (\n                            resp.status in (301, 302) and resp.method == hdrs.METH_POST\n                        ):\n                            method = hdrs.METH_GET\n                            data = None\n                            if headers.get(hdrs.CONTENT_LENGTH):\n                                headers.pop(hdrs.CONTENT_LENGTH)\n\n                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(\n                            hdrs.URI\n                        )\n                        if r_url is None:\n                            # see github.com/aio-libs/aiohttp/issues/2022\n                            break\n                        else:\n                            # reading from correct redirection\n                            # response is forbidden\n                            resp.release()\n\n                        try:\n                            parsed_redirect_url = URL(\n                                r_url, encoded=not self._requote_redirect_url\n                            )\n                        except ValueError as e:\n                            raise InvalidUrlRedirectClientError(\n                                r_url,\n                                \"Server attempted redirecting to a location that does not look like a URL\",\n                            ) from e\n\n                        scheme = parsed_redirect_url.scheme\n                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:\n                            resp.close()\n                            raise NonHttpUrlRedirectClientError(r_url)\n                        elif not scheme:\n                            parsed_redirect_url = url.join(parsed_redirect_url)\n\n                        is_same_host_https_redirect = (\n                            url.host == parsed_redirect_url.host\n                            and parsed_redirect_url.scheme == \"https\"\n                            and url.scheme == \"http\"\n                        )\n\n                        try:\n                            redirect_origin = parsed_redirect_url.origin()\n                        except ValueError as origin_val_err:\n                            raise InvalidUrlRedirectClientError(\n                                parsed_redirect_url,\n                                \"Invalid redirect URL origin\",\n                            ) from origin_val_err\n\n                        if (\n                            url.origin() != redirect_origin\n                            and not is_same_host_https_redirect\n                        ):\n                            auth = None\n                            headers.pop(hdrs.AUTHORIZATION, None)\n\n                        url = parsed_redirect_url\n                        params = {}\n                        resp.release()\n                        continue\n\n                    break\n\n            # check response status\n            if raise_for_status is None:\n                raise_for_status = self._raise_for_status\n\n            if raise_for_status is None:\n                pass\n            elif callable(raise_for_status):\n                await raise_for_status(resp)\n            elif raise_for_status:\n                resp.raise_for_status()\n\n            # register connection\n            if handle is not None:\n                if resp.connection is not None:\n                    resp.connection.add_callback(handle.cancel)\n                else:\n                    handle.cancel()\n\n            resp._history = tuple(history)\n\n            for trace in traces:\n                await trace.send_request_end(\n                    method, url.update_query(params), headers, resp\n                )\n            return resp\n\n        except BaseException as e:\n            # cleanup timer\n            tm.close()\n            if handle:\n                handle.cancel()\n                handle = None\n\n            for trace in traces:\n                await trace.send_request_exception(\n                    method, url.update_query(params), headers, e\n                )\n            raise\n\n    def ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> \"_WSRequestContextManager\":\n        \"\"\"Initiate websocket connection.\"\"\"\n        return _WSRequestContextManager(\n            self._ws_connect(\n                url,\n                method=method,\n                protocols=protocols,\n                timeout=timeout,\n                receive_timeout=receive_timeout,\n                autoclose=autoclose,\n                autoping=autoping,\n                heartbeat=heartbeat,\n                auth=auth,\n                origin=origin,\n                params=params,\n                headers=headers,\n                proxy=proxy,\n                proxy_auth=proxy_auth,\n                ssl=ssl,\n                server_hostname=server_hostname,\n                proxy_headers=proxy_headers,\n                compress=compress,\n                max_msg_size=max_msg_size,\n            )\n        )\n\n    async def _ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> ClientWebSocketResponse:\n        if timeout is sentinel or timeout is None:\n            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT\n        else:\n            if isinstance(timeout, ClientWSTimeout):\n                ws_timeout = timeout\n            else:\n                warnings.warn(\n                    \"parameter 'timeout' of type 'float' \"\n                    \"is deprecated, please use \"\n                    \"'timeout=ClientWSTimeout(ws_close=...)'\",\n                    DeprecationWarning,\n                    stacklevel=2,\n                )\n                ws_timeout = ClientWSTimeout(ws_close=timeout)\n\n        if receive_timeout is not None:\n            warnings.warn(\n                \"float parameter 'receive_timeout' \"\n                \"is deprecated, please use parameter \"\n                \"'timeout=ClientWSTimeout(ws_receive=...)'\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)\n\n        if headers is None:\n            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        default_headers = {\n            hdrs.UPGRADE: \"websocket\",\n            hdrs.CONNECTION: \"Upgrade\",\n            hdrs.SEC_WEBSOCKET_VERSION: \"13\",\n        }\n\n        for key, value in default_headers.items():\n            real_headers.setdefault(key, value)\n\n        sec_key = base64.b64encode(os.urandom(16))\n        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()\n\n        if protocols:\n            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = \",\".join(protocols)\n        if origin is not None:\n            real_headers[hdrs.ORIGIN] = origin\n        if compress:\n            extstr = ws_ext_gen(compress=compress)\n            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        # send request\n        resp = await self.request(\n            method,\n            url,\n            params=params,\n            headers=real_headers,\n            read_until_eof=False,\n            auth=auth,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            ssl=ssl,\n            server_hostname=server_hostname,\n            proxy_headers=proxy_headers,\n        )\n\n        try:\n            # check handshake\n            if resp.status != 101:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid response status\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.UPGRADE, \"\").lower() != \"websocket\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid upgrade header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.CONNECTION, \"\").lower() != \"upgrade\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid connection header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # key calculation\n            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, \"\")\n            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()\n            if r_key != match:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid challenge response\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # websocket protocol\n            protocol = None\n            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:\n                resp_protocols = [\n                    proto.strip()\n                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(\",\")\n                ]\n\n                for proto in resp_protocols:\n                    if proto in protocols:\n                        protocol = proto\n                        break\n\n            # websocket compress\n            notakeover = False\n            if compress:\n                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)\n                if compress_hdrs:\n                    try:\n                        compress, notakeover = ws_ext_parse(compress_hdrs)\n                    except WSHandshakeError as exc:\n                        raise WSServerHandshakeError(\n                            resp.request_info,\n                            resp.history,\n                            message=exc.args[0],\n                            status=resp.status,\n                            headers=resp.headers,\n                        ) from exc\n                else:\n                    compress = 0\n                    notakeover = False\n\n            conn = resp.connection\n            assert conn is not None\n            conn_proto = conn.protocol\n            assert conn_proto is not None\n\n            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater\n            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible\n            if ws_timeout.ws_receive is None:\n                # Reset regardless\n                conn_proto.read_timeout = None\n            elif conn_proto.read_timeout is not None:\n                conn_proto.read_timeout = max(\n                    ws_timeout.ws_receive, conn_proto.read_timeout\n                )\n\n            transport = conn.transport\n            assert transport is not None\n            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(\n                conn_proto, 2**16, loop=self._loop\n            )\n            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)\n            writer = WebSocketWriter(\n                conn_proto,\n                transport,\n                use_mask=True,\n                compress=compress,\n                notakeover=notakeover,\n            )\n        except BaseException:\n            resp.close()\n            raise\n        else:\n            return self._ws_response_class(\n                reader,\n                writer,\n                protocol,\n                resp,\n                ws_timeout,\n                autoclose,\n                autoping,\n                self._loop,\n                heartbeat=heartbeat,\n                compress=compress,\n                client_notakeover=notakeover,\n            )\n\n    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> \"CIMultiDict[str]\":\n        \"\"\"Add default headers and transform it to CIMultiDict\"\"\"\n        # Convert headers to MultiDict\n        result = CIMultiDict(self._default_headers)\n        if headers:\n            if not isinstance(headers, (MultiDictProxy, MultiDict)):\n                headers = CIMultiDict(headers)\n            added_names: Set[str] = set()\n            for key, value in headers.items():\n                if key in added_names:\n                    result.add(key, value)\n                else:\n                    result[key] = value\n                    added_names.add(key)\n        return result\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def get(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def options(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def head(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def post(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def put(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def patch(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def delete(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def get(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP GET request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def options(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP OPTIONS request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def head(\n            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP HEAD request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def post(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP POST request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_POST, url, data=data, **kwargs)\n            )\n\n        def put(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PUT request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PUT, url, data=data, **kwargs)\n            )\n\n        def patch(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PATCH request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)\n            )\n\n        def delete(self, url: StrOrURL, **kwargs: Any) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP DELETE request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_DELETE, url, **kwargs)\n            )\n\n    async def close(self) -> None:\n        \"\"\"Close underlying connector.\n\n        Release all acquired resources.\n        \"\"\"\n        if not self.closed:\n            if self._connector is not None and self._connector_owner:\n                await self._connector.close()\n            self._connector = None\n\n    @property\n    def closed(self) -> bool:\n        \"\"\"Is client session closed.\n\n        A readonly property.\n        \"\"\"\n        return self._connector is None or self._connector.closed\n\n    @property\n    def connector(self) -> Optional[BaseConnector]:\n        \"\"\"Connector instance used for the session.\"\"\"\n        return self._connector\n\n    @property\n    def cookie_jar(self) -> AbstractCookieJar:\n        \"\"\"The session cookies.\"\"\"\n        return self._cookie_jar\n\n    @property\n    def version(self) -> Tuple[int, int]:\n        \"\"\"The session HTTP protocol version.\"\"\"\n        return self._version\n\n    @property\n    def requote_redirect_url(self) -> bool:\n        \"\"\"Do URL requoting on redirection handling.\"\"\"\n        return self._requote_redirect_url\n\n    @property\n    def timeout(self) -> ClientTimeout:\n        \"\"\"Timeout for the session.\"\"\"\n        return self._timeout\n\n    @property\n    def headers(self) -> \"CIMultiDict[str]\":\n        \"\"\"The default headers of the client session.\"\"\"\n        return self._default_headers\n\n    @property\n    def skip_auto_headers(self) -> FrozenSet[istr]:\n        \"\"\"Headers for which autogeneration should be skipped\"\"\"\n        return self._skip_auto_headers\n\n    @property\n    def auth(self) -> Optional[BasicAuth]:\n        \"\"\"An object that represents HTTP Basic Authorization\"\"\"\n        return self._default_auth\n\n    @property\n    def json_serialize(self) -> JSONEncoder:\n        \"\"\"Json serializer callable\"\"\"\n        return self._json_serialize\n\n    @property\n    def connector_owner(self) -> bool:\n        \"\"\"Should connector be closed on session closing\"\"\"\n        return self._connector_owner\n\n    @property\n    def raise_for_status(\n        self,\n    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:\n        \"\"\"Should `ClientResponse.raise_for_status()` be called for each response.\"\"\"\n        return self._raise_for_status\n\n    @property\n    def auto_decompress(self) -> bool:\n        \"\"\"Should the body response be automatically decompressed.\"\"\"\n        return self._auto_decompress\n\n    @property\n    def trust_env(self) -> bool:\n        \"\"\"\n        Should proxies information from environment or netrc be trusted.\n\n        Information is from HTTP_PROXY / HTTPS_PROXY environment variables\n        or ~/.netrc file if present.\n        \"\"\"\n        return self._trust_env\n\n    @property\n    def trace_configs(self) -> List[TraceConfig[Any]]:\n        \"\"\"A list of TraceConfig instances used for client tracing\"\"\"\n        return self._trace_configs\n\n    def detach(self) -> None:\n        \"\"\"Detach connector from session without closing the former.\n\n        Session is switched to closed state anyway.\n        \"\"\"\n        self._connector = None\n\n    async def __aenter__(self) -> \"ClientSession\":\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        await self.close()",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 225,
                                "end_lineno": 1266,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": ".. _aiohttp-client-reference:\n\nClient Reference\n================\n\n.. currentmodule:: aiohttp\n\n\nClient Session\n--------------\n\nClient session is the recommended interface for making HTTP requests.\n\nSession encapsulates a *connection pool* (*connector* instance) and\nsupports keepalives by default. Unless you are connecting to a large,\nunknown number of different servers over the lifetime of your\napplication, it is suggested you use a single session for the\nlifetime of your application to benefit from connection pooling.\n\nUsage example::\n\n     import aiohttp\n     import asyncio\n\n     async def fetch(client):\n         async with client.get('http://python.org') as resp:\n             assert resp.status == 200\n             return await resp.text()\n\n     async def main():\n         async with aiohttp.ClientSession() as client:\n             html = await fetch(client)\n             print(html)\n\n     asyncio.run(main())\n\n\nThe client session supports the context manager protocol for self closing.\n\n.. class:: ClientSession(base_url=None, *, \\\n                         connector=None, cookies=None, \\\n                         headers=None, skip_auto_headers=None, \\\n                         auth=None, json_serialize=json.dumps, \\\n                         version=aiohttp.HttpVersion11, \\\n                         cookie_jar=None, read_timeout=None, \\\n                         conn_timeout=None, \\\n                         timeout=sentinel, \\\n                         raise_for_status=False, \\\n                         connector_owner=True, \\\n                         auto_decompress=True, \\\n                         read_bufsize=2**16, \\\n                         requote_redirect_url=True, \\\n                         trust_env=False, \\\n                         trace_configs=None, \\\n                         fallback_charset_resolver=lambda r, b: \"utf-8\")\n\n   The class for creating client sessions and making requests.\n\n\n   :param base_url: Base part of the URL (optional)\n      If set, it allows to skip the base part (https://docs.aiohttp.org) in\n      request calls. It must not include a path (as in\n      https://docs.aiohttp.org/en/stable).\n\n      .. versionadded:: 3.8\n\n   :param aiohttp.BaseConnector connector: BaseConnector\n      sub-class instance to support connection pooling.\n\n   :param loop: :ref:`event loop<asyncio-event-loop>` used for\n      processing HTTP requests.\n\n      If *loop* is ``None`` the constructor\n      borrows it from *connector* if specified.\n\n      :func:`asyncio.get_event_loop` is used for getting default event\n      loop otherwise.\n\n      .. deprecated:: 2.0\n\n   :param dict cookies: Cookies to send with the request (optional)\n\n   :param headers: HTTP Headers to send with every request (optional).\n\n                   May be either *iterable of key-value pairs* or\n                   :class:`~collections.abc.Mapping`\n                   (e.g. :class:`dict`,\n                   :class:`~multidict.CIMultiDict`).\n\n   :param skip_auto_headers: set of headers for which autogeneration\n      should be skipped.\n\n      *aiohttp* autogenerates headers like ``User-Agent`` or\n      ``Content-Type`` if these headers are not explicitly\n      passed. Using ``skip_auto_headers`` parameter allows to skip\n      that generation. Note that ``Content-Length`` autogeneration can't\n      be skipped.\n\n      Iterable of :class:`str` or :class:`~multidict.istr` (optional)\n\n   :param aiohttp.BasicAuth auth: an object that represents HTTP Basic\n                                  Authorization (optional). It will be included\n                                  with any request to any origin and will not be\n                                  removed, event during redirect to a different\n                                  origin.\n\n   :param version: supported HTTP version, ``HTTP 1.1`` by default.\n\n   :param cookie_jar: Cookie Jar, :class:`~aiohttp.abc.AbstractCookieJar` instance.\n\n      By default every session instance has own private cookie jar for\n      automatic cookies processing but user may redefine this behavior\n      by providing own jar implementation.\n\n      One example is not processing cookies at all when working in\n      proxy mode.\n\n      If no cookie processing is needed, a\n      :class:`aiohttp.DummyCookieJar` instance can be\n      provided.\n\n   :param collections.abc.Callable json_serialize: Json *serializer* callable.\n\n      By default :func:`json.dumps` function.\n\n   :param bool raise_for_status:\n\n      Automatically call :meth:`ClientResponse.raise_for_status()` for\n      each response, ``False`` by default.\n\n      This parameter can be overridden when making a request, e.g.::\n\n          client_session = aiohttp.ClientSession(raise_for_status=True)\n          resp = await client_session.get(url, raise_for_status=False)\n          async with resp:\n              assert resp.status == 200\n\n      Set the parameter to ``True`` if you need ``raise_for_status``\n      for most of cases but override ``raise_for_status`` for those\n      requests where you need to handle responses with status 400 or\n      higher.\n\n   :param timeout: a :class:`ClientTimeout` settings structure, 300 seconds (5min)\n        total timeout by default.\n\n      .. versionadded:: 3.3\n\n   :param float read_timeout: Request operations timeout. ``read_timeout`` is\n      cumulative for all request operations (request, redirects, responses,\n      data consuming). By default, the read timeout is 5*60 seconds.\n      Use ``None`` or ``0`` to disable timeout checks.\n\n      .. deprecated:: 3.3\n\n         Use ``timeout`` parameter instead.\n\n   :param float conn_timeout: timeout for connection establishing\n      (optional). Values ``0`` or ``None`` mean no timeout.\n\n      .. deprecated:: 3.3\n\n         Use ``timeout`` parameter instead.\n\n   :param bool connector_owner:\n\n      Close connector instance on session closing.\n\n      Setting the parameter to ``False`` allows to share\n      connection pool between sessions without sharing session state:\n      cookies etc.\n\n   :param bool auto_decompress: Automatically decompress response body (``True`` by default).\n\n      .. versionadded:: 2.3\n\n   :param int read_bufsize: Size of the read buffer (:attr:`ClientResponse.content`).\n                            64 KiB by default.\n\n      .. versionadded:: 3.7\n\n   :param bool trust_env: Trust environment settings for proxy configuration if the parameter\n      is ``True`` (``False`` by default). See :ref:`aiohttp-client-proxy-support` for\n      more information.\n\n      Get proxy credentials from ``~/.netrc`` file if present.\n\n      Get HTTP Basic Auth credentials from :file:`~/.netrc` file if present.\n\n      If :envvar:`NETRC` environment variable is set, read from file specified\n      there rather than from :file:`~/.netrc`.\n\n      .. seealso::\n\n         ``.netrc`` documentation: https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html\n\n      .. versionadded:: 2.3\n\n      .. versionchanged:: 3.0\n\n         Added support for ``~/.netrc`` file.\n\n      .. versionchanged:: 3.9\n\n         Added support for reading HTTP Basic Auth credentials from :file:`~/.netrc` file.\n\n   :param bool requote_redirect_url: Apply *URL requoting* for redirection URLs if\n                                     automatic redirection is enabled (``True`` by\n                                     default).\n\n      .. versionadded:: 3.5\n\n   :param trace_configs: A list of :class:`TraceConfig` instances used for client\n                         tracing.  ``None`` (default) is used for request tracing\n                         disabling.  See :ref:`aiohttp-client-tracing-reference` for\n                         more information.\n\n   :param Callable[[ClientResponse,bytes],str] fallback_charset_resolver:\n      A :term:`callable` that accepts a :class:`ClientResponse` and the\n      :class:`bytes` contents, and returns a :class:`str` which will be used as\n      the encoding parameter to :meth:`bytes.decode()`.\n\n      This function will be called when the charset is not known (e.g. not specified in the\n      Content-Type header). The default function simply defaults to ``utf-8``.\n\n      .. versionadded:: 3.8.6\n\n   .. attribute:: closed\n\n      ``True`` if the session has been closed, ``False`` otherwise.\n\n      A read-only property.\n\n   .. attribute:: connector\n\n      :class:`aiohttp.BaseConnector` derived instance used\n      for the session.\n\n      A read-only property.\n\n   .. attribute:: cookie_jar\n\n      The session cookies, :class:`~aiohttp.abc.AbstractCookieJar` instance.\n\n      Gives access to cookie jar's content and modifiers.\n\n      A read-only property.\n\n   .. attribute:: requote_redirect_url\n\n      aiohttp re quote's redirect urls by default, but some servers\n      require exact url from location header. To disable *re-quote* system\n      set :attr:`requote_redirect_url` attribute to ``False``.\n\n      .. versionadded:: 2.1\n\n      .. note:: This parameter affects all subsequent requests.\n\n      .. deprecated:: 3.5\n\n         The attribute modification is deprecated.\n\n   .. attribute:: loop\n\n      A loop instance used for session creation.\n\n      A read-only property.\n\n      .. deprecated:: 3.5\n\n   .. attribute:: timeout\n\n      Default client timeouts, :class:`ClientTimeout` instance.  The value can\n      be tuned by passing *timeout* parameter to :class:`ClientSession`\n      constructor.\n\n      .. versionadded:: 3.7\n\n   .. attribute:: headers\n\n      HTTP Headers that sent with every request\n\n      May be either *iterable of key-value pairs* or\n      :class:`~collections.abc.Mapping`\n      (e.g. :class:`dict`,\n      :class:`~multidict.CIMultiDict`).\n\n      .. versionadded:: 3.7\n\n   .. attribute:: skip_auto_headers\n\n      Set of headers for which autogeneration skipped.\n\n      :class:`frozenset` of :class:`str` or :class:`~multidict.istr` (optional)\n\n      .. versionadded:: 3.7\n\n   .. attribute:: auth\n\n      An object that represents HTTP Basic Authorization.\n\n      :class:`~aiohttp.BasicAuth` (optional)\n\n      .. versionadded:: 3.7\n\n   .. attribute:: json_serialize\n\n      Json serializer callable.\n\n      By default :func:`json.dumps` function.\n\n      .. versionadded:: 3.7\n\n   .. attribute:: connector_owner\n\n      Should connector be closed on session closing\n\n      :class:`bool` (optional)\n\n      .. versionadded:: 3.7\n\n   .. attribute:: raise_for_status\n\n      Should :meth:`ClientResponse.raise_for_status()` be called for each response\n\n      Either :class:`bool` or :class:`collections.abc.Callable`\n\n      .. versionadded:: 3.7\n\n   .. attribute:: auto_decompress\n\n      Should the body response be automatically decompressed\n\n      :class:`bool` default is ``True``\n\n      .. versionadded:: 3.7\n\n   .. attribute:: trust_env\n\n      Trust environment settings for proxy configuration\n      or ~/.netrc file if present. See :ref:`aiohttp-client-proxy-support` for\n      more information.\n\n      :class:`bool` default is ``False``\n\n      .. versionadded:: 3.7\n\n   .. attribute:: trace_config\n\n      A list of :class:`TraceConfig` instances used for client\n      tracing.  ``None`` (default) is used for request tracing\n      disabling.  See :ref:`aiohttp-client-tracing-reference` for more information.\n\n      .. versionadded:: 3.7\n\n   .. method:: request(method, url, *, params=None, data=None, json=None,\\\n                         cookies=None, headers=None, skip_auto_headers=None, \\\n                         auth=None, allow_redirects=True,\\\n                         max_redirects=10,\\\n                         compress=None, chunked=None, expect100=False, raise_for_status=None,\\\n                         read_until_eof=True, \\\n                         read_bufsize=None, \\\n                         proxy=None, proxy_auth=None,\\\n                         timeout=sentinel, ssl=True, \\\n                         verify_ssl=None, fingerprint=None, \\\n                         ssl_context=None, proxy_headers=None, \\\n                         server_hostname=None, auto_decompress=None)\n      :async:\n      :noindexentry:\n\n      Performs an asynchronous HTTP request. Returns a response object that\n      should be used as an async context manager.\n\n      :param str method: HTTP method\n\n      :param url: Request URL, :class:`~yarl.URL` or :class:`str` that will\n                  be encoded with :class:`~yarl.URL` (see :class:`~yarl.URL`\n                  to skip encoding).\n\n      :param params: Mapping, iterable of tuple of *key*/*value* pairs or\n                     string to be sent as parameters in the query\n                     string of the new request. Ignored for subsequent\n                     redirected requests (optional)\n\n                     Allowed values are:\n\n                     - :class:`collections.abc.Mapping` e.g. :class:`dict`,\n                       :class:`multidict.MultiDict` or\n                       :class:`multidict.MultiDictProxy`\n                     - :class:`collections.abc.Iterable` e.g. :class:`tuple` or\n                       :class:`list`\n                     - :class:`str` with preferably url-encoded content\n                       (**Warning:** content will not be encoded by *aiohttp*)\n\n      :param data: The data to send in the body of the request. This can be a\n                   :class:`FormData` object or anything that can be passed into\n                   :class:`FormData`, e.g. a dictionary, bytes, or file-like object.\n                   (optional)\n\n      :param json: Any json compatible python object\n                   (optional). *json* and *data* parameters could not\n                   be used at the same time.\n\n      :param dict cookies: HTTP Cookies to send with\n                           the request (optional)\n\n         Global session cookies and the explicitly set cookies will be merged\n         when sending the request.\n\n         .. versionadded:: 3.5\n\n      :param dict headers: HTTP Headers to send with\n                           the request (optional)\n\n      :param skip_auto_headers: set of headers for which autogeneration\n         should be skipped.\n\n         *aiohttp* autogenerates headers like ``User-Agent`` or\n         ``Content-Type`` if these headers are not explicitly\n         passed. Using ``skip_auto_headers`` parameter allows to skip\n         that generation.\n\n         Iterable of :class:`str` or :class:`~multidict.istr`\n         (optional)\n\n      :param aiohttp.BasicAuth auth: an object that represents HTTP\n                                     Basic Authorization (optional)\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``True`` by default (optional).\n\n      :param int max_redirects: Maximum number of redirects to follow.\n                                ``10`` by default.\n\n      :param bool compress: Set to ``True`` if request has to be compressed\n         with deflate encoding. If `compress` can not be combined\n         with a *Content-Encoding* and *Content-Length* headers.\n         ``None`` by default (optional).\n\n      :param int chunked: Enable chunked transfer encoding.\n         It is up to the developer\n         to decide how to chunk data streams. If chunking is enabled, aiohttp\n         encodes the provided chunks in the \"Transfer-encoding: chunked\" format.\n         If *chunked* is set, then the *Transfer-encoding* and *content-length*\n         headers are disallowed. ``None`` by default (optional).\n\n      :param bool expect100: Expect 100-continue response from server.\n                             ``False`` by default (optional).\n\n      :param bool raise_for_status: Automatically call :meth:`ClientResponse.raise_for_status()` for\n                                    response if set to ``True``.\n                                    If set to ``None`` value from ``ClientSession`` will be used.\n                                    ``None`` by default (optional).\n\n          .. versionadded:: 3.4\n\n      :param bool read_until_eof: Read response until EOF if response\n                                  does not have Content-Length header.\n                                  ``True`` by default (optional).\n\n      :param int read_bufsize: Size of the read buffer (:attr:`ClientResponse.content`).\n                              ``None`` by default,\n                              it means that the session global value is used.\n\n          .. versionadded:: 3.7\n\n      :param proxy: Proxy URL, :class:`str` or :class:`~yarl.URL` (optional)\n\n      :param aiohttp.BasicAuth proxy_auth: an object that represents proxy HTTP\n                                           Basic Authorization (optional)\n\n      :param int timeout: override the session's timeout.\n\n         .. versionchanged:: 3.3\n\n            The parameter is :class:`ClientTimeout` instance,\n            :class:`float` is still supported for sake of backward\n            compatibility.\n\n            If :class:`float` is passed it is a *total* timeout (in seconds).\n\n      :param ssl: SSL validation mode. ``True`` for default SSL check\n                  (:func:`ssl.create_default_context` is used),\n                  ``False`` for skip SSL certificate validation,\n                  :class:`aiohttp.Fingerprint` for fingerprint\n                  validation, :class:`ssl.SSLContext` for custom SSL\n                  certificate validation.\n\n                  Supersedes *verify_ssl*, *ssl_context* and\n                  *fingerprint* parameters.\n\n         .. versionadded:: 3.0\n\n      :param bool verify_ssl: Perform SSL certificate validation for\n         *HTTPS* requests (enabled by default). May be disabled to\n         skip validation for sites with invalid certificates.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=False``\n\n      :param bytes fingerprint: Pass the SHA256 digest of the expected\n         certificate in DER format to verify that the certificate the\n         server presents matches. Useful for `certificate pinning\n         <https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning>`_.\n\n         Warning: use of MD5 or SHA1 digests is insecure and removed.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=aiohttp.Fingerprint(digest)``\n\n      :param str server_hostname: Sets or overrides the host name that the\n         target server’s certificate will be matched against.\n\n         See :py:meth:`asyncio.loop.create_connection` for more information.\n\n         .. versionadded:: 3.9\n\n      :param ssl.SSLContext ssl_context: ssl context used for processing\n         *HTTPS* requests (optional).\n\n         *ssl_context* may be used for configuring certification\n         authority channel, supported SSL options etc.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=ssl_context``\n\n      :param collections.abc.Mapping proxy_headers: HTTP headers to send to the proxy if the\n         parameter proxy has been provided.\n\n         .. versionadded:: 2.3\n\n      :param trace_request_ctx: Object used to give as a kw param for each new\n        :class:`TraceConfig` object instantiated,\n        used to give information to the\n        tracers that is only available at request time.\n\n         .. versionadded:: 3.0\n\n      :param bool auto_decompress: Automatically decompress response body.\n         Overrides :attr:`ClientSession.auto_decompress`.\n         May be used to enable/disable auto decompression on a per-request basis.\n\n      :return ClientResponse: a :class:`client response <ClientResponse>`\n         object.\n\n   .. method:: get(url, *, allow_redirects=True, **kwargs)\n      :async:\n\n      Perform a ``GET`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``True`` by default (optional).\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: post(url, *, data=None, **kwargs)\n      :async:\n\n      Perform a ``POST`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param data: Data to send in the body of the request; see\n                   :meth:`request<aiohttp.ClientSession.request>`\n                   for details (optional)\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: put(url, *, data=None, **kwargs)\n      :async:\n\n      Perform a ``PUT`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param data: Data to send in the body of the request; see\n                   :meth:`request<aiohttp.ClientSession.request>`\n                   for details (optional)\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: delete(url, **kwargs)\n      :async:\n\n      Perform a ``DELETE`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: head(url, *, allow_redirects=False, **kwargs)\n      :async:\n\n      Perform a ``HEAD`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``False`` by default (optional).\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: options(url, *, allow_redirects=True, **kwargs)\n      :async:\n\n      Perform an ``OPTIONS`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``True`` by default (optional).\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: patch(url, *, data=None, **kwargs)\n      :async:\n\n      Perform a ``PATCH`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param data: Data to send in the body of the request; see\n                   :meth:`request<aiohttp.ClientSession.request>`\n                   for details (optional)\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: ws_connect(url, *, method='GET', \\\n                            protocols=(), timeout=10.0,\\\n                            receive_timeout=None,\\\n                            auth=None,\\\n                            autoclose=True,\\\n                            autoping=True,\\\n                            heartbeat=None,\\\n                            origin=None, \\\n                            params=None, \\\n                            headers=None, \\\n                            proxy=None, proxy_auth=None, ssl=True, \\\n                            verify_ssl=None, fingerprint=None, \\\n                            ssl_context=None, proxy_headers=None, \\\n                            compress=0, max_msg_size=4194304)\n      :async:\n\n      Create a websocket connection. Returns a\n      :class:`ClientWebSocketResponse` async context manager object.\n\n      :param url: Websocket server url, :class:`~yarl.URL` or :class:`str` that\n                  will be encoded with :class:`~yarl.URL` (see :class:`~yarl.URL`\n                  to skip encoding).\n\n      :param tuple protocols: Websocket protocols\n\n      :param float timeout: Timeout for websocket to close. ``10`` seconds\n                            by default\n\n      :param float receive_timeout: Timeout for websocket to receive\n                                    complete message.  ``None`` (unlimited)\n                                    seconds by default\n\n      :param aiohttp.BasicAuth auth: an object that represents HTTP\n                                     Basic Authorization (optional)\n\n      :param bool autoclose: Automatically close websocket connection on close\n                             message from server. If *autoclose* is False\n                             then close procedure has to be handled manually.\n                             ``True`` by default\n\n      :param bool autoping: automatically send *pong* on *ping*\n                            message from server. ``True`` by default\n\n      :param float heartbeat: Send *ping* message every *heartbeat*\n                              seconds and wait *pong* response, if\n                              *pong* response is not received then\n                              close connection. The timer is reset on any data\n                              reception.(optional)\n\n      :param str origin: Origin header to send to server(optional)\n\n      :param params: Mapping, iterable of tuple of *key*/*value* pairs or\n                     string to be sent as parameters in the query\n                     string of the new request. Ignored for subsequent\n                     redirected requests (optional)\n\n                     Allowed values are:\n\n                     - :class:`collections.abc.Mapping` e.g. :class:`dict`,\n                       :class:`multidict.MultiDict` or\n                       :class:`multidict.MultiDictProxy`\n                     - :class:`collections.abc.Iterable` e.g. :class:`tuple` or\n                       :class:`list`\n                     - :class:`str` with preferably url-encoded content\n                       (**Warning:** content will not be encoded by *aiohttp*)\n\n      :param dict headers: HTTP Headers to send with\n                           the request (optional)\n\n      :param str proxy: Proxy URL, :class:`str` or :class:`~yarl.URL` (optional)\n\n      :param aiohttp.BasicAuth proxy_auth: an object that represents proxy HTTP\n                                           Basic Authorization (optional)\n\n      :param ssl: SSL validation mode. ``True`` for default SSL check\n                  (:func:`ssl.create_default_context` is used),\n                  ``False`` for skip SSL certificate validation,\n                  :class:`aiohttp.Fingerprint` for fingerprint\n                  validation, :class:`ssl.SSLContext` for custom SSL\n                  certificate validation.\n\n                  Supersedes *verify_ssl*, *ssl_context* and\n                  *fingerprint* parameters.\n\n         .. versionadded:: 3.0\n\n      :param bool verify_ssl: Perform SSL certificate validation for\n         *HTTPS* requests (enabled by default). May be disabled to\n         skip validation for sites with invalid certificates.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=False``\n\n      :param bytes fingerprint: Pass the SHA256 digest of the expected\n         certificate in DER format to verify that the certificate the\n         server presents matches. Useful for `certificate pinning\n         <https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning>`_.\n\n         Note: use of MD5 or SHA1 digests is insecure and deprecated.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=aiohttp.Fingerprint(digest)``\n\n      :param ssl.SSLContext ssl_context: ssl context used for processing\n         *HTTPS* requests (optional).\n\n         *ssl_context* may be used for configuring certification\n         authority channel, supported SSL options etc.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=ssl_context``\n\n      :param dict proxy_headers: HTTP headers to send to the proxy if the\n         parameter proxy has been provided.\n\n         .. versionadded:: 2.3\n\n      :param int compress: Enable Per-Message Compress Extension support.\n                           0 for disable, 9 to 15 for window bit support.\n                           Default value is 0.\n\n         .. versionadded:: 2.3\n\n      :param int max_msg_size: maximum size of read websocket message,\n                               4 MB by default. To disable the size\n                               limit use ``0``.\n\n         .. versionadded:: 3.3\n\n      :param str method: HTTP method to establish WebSocket connection,\n                         ``'GET'`` by default.\n\n         .. versionadded:: 3.5\n\n\n   .. method:: close()\n      :async:\n\n      Close underlying connector.\n\n      Release all acquired resources.\n\n   .. method:: detach()\n\n      Detach connector from session without closing the former.\n\n      Session is switched to closed state anyway.\n\n\n\nBasic API\n---------\n\nWhile we encourage :class:`ClientSession` usage we also provide simple\ncoroutines for making HTTP requests.\n\nBasic API is good for performing simple HTTP requests without\nkeepaliving, cookies and complex connection stuff like properly configured SSL\ncertification chaining.\n\n\n.. function:: request(method, url, *, params=None, data=None, \\\n                        json=None,\\\n                        headers=None, cookies=None, auth=None, \\\n                        allow_redirects=True, max_redirects=10, \\\n                        encoding='utf-8', \\\n                        version=HttpVersion(major=1, minor=1), \\\n                        compress=None, chunked=None, expect100=False, raise_for_status=False, \\\n                        read_bufsize=None, \\\n                        connector=None, loop=None,\\\n                        read_until_eof=True, timeout=sentinel)\n   :async:\n\n   Asynchronous context manager for performing an asynchronous HTTP\n   request. Returns a :class:`ClientResponse` response object. Use as\n   an async context manager.\n\n   :param str method: HTTP method\n\n   :param url: Request URL, :class:`~yarl.URL` or :class:`str` that will\n               be encoded with :class:`~yarl.URL` (see :class:`~yarl.URL`\n               to skip encoding).\n\n   :param dict params: Parameters to be sent in the query\n                       string of the new request (optional)\n\n   :param data: The data to send in the body of the request. This can be a\n                :class:`FormData` object or anything that can be passed into\n                :class:`FormData`, e.g. a dictionary, bytes, or file-like object.\n                (optional)\n\n   :param json: Any json compatible python object (optional). *json* and *data*\n                parameters could not be used at the same time.\n\n   :param dict headers: HTTP Headers to send with the request (optional)\n\n   :param dict cookies: Cookies to send with the request (optional)\n\n   :param aiohttp.BasicAuth auth: an object that represents HTTP Basic\n                                  Authorization (optional)\n\n   :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                ``True`` by default (optional).\n\n   :param aiohttp.protocol.HttpVersion version: Request HTTP version (optional)\n\n   :param bool compress: Set to ``True`` if request has to be compressed\n                         with deflate encoding.\n                         ``False`` instructs aiohttp to not compress data.\n                         ``None`` by default (optional).\n\n   :param int chunked: Enables chunked transfer encoding.\n                       ``None`` by default (optional).\n\n   :param bool expect100: Expect 100-continue response from server.\n                          ``False`` by default (optional).\n\n   :param bool raise_for_status: Automatically call\n                                 :meth:`ClientResponse.raise_for_status()`\n                                 for response if set to ``True``.  If\n                                 set to ``None`` value from\n                                 ``ClientSession`` will be used.\n                                 ``None`` by default (optional).\n\n      .. versionadded:: 3.4\n\n   :param aiohttp.BaseConnector connector: BaseConnector sub-class\n      instance to support connection pooling.\n\n   :param bool read_until_eof: Read response until EOF if response\n                               does not have Content-Length header.\n                               ``True`` by default (optional).\n\n   :param int read_bufsize: Size of the read buffer (:attr:`ClientResponse.content`).\n                            ``None`` by default,\n                            it means that the session global value is used.\n\n      .. versionadded:: 3.7\n\n   :param timeout: a :class:`ClientTimeout` settings structure, 300 seconds (5min)\n        total timeout by default.\n\n   :param loop: :ref:`event loop<asyncio-event-loop>`\n                used for processing HTTP requests.\n                If param is ``None``, :func:`asyncio.get_event_loop`\n                is used for getting default event loop.\n\n      .. deprecated:: 2.0\n\n   :return ClientResponse: a :class:`client response <ClientResponse>` object.\n\n   Usage::\n\n      import aiohttp\n\n      async def fetch():\n          async with aiohttp.request('GET',\n                  'http://python.org/') as resp:\n              assert resp.status == 200\n              print(await resp.text())\n\n\n.. _aiohttp-client-reference-connectors:\n\nConnectors\n----------\n\nConnectors are transports for aiohttp client API.\n\nThere are standard connectors:\n\n1. :class:`TCPConnector` for regular *TCP sockets* (both *HTTP* and\n   *HTTPS* schemes supported).\n2. :class:`UnixConnector` for connecting via UNIX socket (it's used mostly for\n   testing purposes).\n\nAll connector classes should be derived from :class:`BaseConnector`.\n\nBy default all *connectors* support *keep-alive connections* (behavior\nis controlled by *force_close* constructor's parameter).\n\n\n.. class:: BaseConnector(*, keepalive_timeout=15, \\\n                         force_close=False, limit=100, limit_per_host=0, \\\n                         enable_cleanup_closed=False, loop=None)\n\n   Base class for all connectors.\n\n   :param float keepalive_timeout: timeout for connection reusing\n                                   after releasing (optional). Values\n                                   ``0``. For disabling *keep-alive*\n                                   feature use ``force_close=True``\n                                   flag.\n\n   :param int limit: total number simultaneous connections. If *limit* is\n                     ``0`` the connector has no limit (default: 100).\n\n   :param int limit_per_host: limit simultaneous connections to the same\n      endpoint.  Endpoints are the same if they are\n      have equal ``(host, port, is_ssl)`` triple.\n      If *limit* is ``0`` the connector has no limit (default: 0).\n\n   :param bool force_close: close underlying sockets after\n                            connection releasing (optional).\n\n   :param bool enable_cleanup_closed: some SSL servers do not properly complete\n      SSL shutdown process, in that case asyncio leaks ssl connections.\n      If this parameter is set to True, aiohttp additionally aborts underlining\n      transport after 2 seconds. It is off by default.\n\n\n   :param loop: :ref:`event loop<asyncio-event-loop>`\n      used for handling connections.\n      If param is ``None``, :func:`asyncio.get_event_loop`\n      is used for getting default event loop.\n\n      .. deprecated:: 2.0\n\n   .. attribute:: closed\n\n      Read-only property, ``True`` if connector is closed.\n\n   .. attribute:: force_close\n\n      Read-only property, ``True`` if connector should ultimately\n      close connections on releasing.\n\n   .. attribute:: limit\n\n      The total number for simultaneous connections.\n      If limit is 0 the connector has no limit. The default limit size is 100.\n\n   .. attribute:: limit_per_host\n\n      The limit for simultaneous connections to the same\n      endpoint.\n\n      Endpoints are the same if they are have equal ``(host, port,\n      is_ssl)`` triple.\n\n      If *limit_per_host* is ``0`` the connector has no limit per host.\n\n      Read-only property.\n\n   .. method:: close()\n      :async:\n\n      Close all opened connections.\n\n   .. method:: connect(request)\n      :async:\n\n      Get a free connection from pool or create new one if connection\n      is absent in the pool.\n\n      The call may be paused if :attr:`limit` is exhausted until used\n      connections returns to pool.\n\n      :param aiohttp.ClientRequest request: request object\n                                                   which is connection\n                                                   initiator.\n\n      :return: :class:`Connection` object.\n\n   .. method:: _create_connection(req)\n      :async:\n\n      Abstract method for actual connection establishing, should be\n      overridden in subclasses.\n\n\n.. class:: TCPConnector(*, ssl=True, verify_ssl=True, fingerprint=None, \\\n                 use_dns_cache=True, ttl_dns_cache=10, \\\n                 family=0, ssl_context=None, local_addr=None, \\\n                 resolver=None, keepalive_timeout=sentinel, \\\n                 force_close=False, limit=100, limit_per_host=0, \\\n                 enable_cleanup_closed=False, timeout_ceil_threshold=5, \\\n                 happy_eyeballs_delay=0.25, interleave=None, loop=None)\n\n   Connector for working with *HTTP* and *HTTPS* via *TCP* sockets.\n\n   The most common transport. When you don't know what connector type\n   to use, use a :class:`TCPConnector` instance.\n\n   :class:`TCPConnector` inherits from :class:`BaseConnector`.\n\n   Constructor accepts all parameters suitable for\n   :class:`BaseConnector` plus several TCP-specific ones:\n\n      :param ssl: SSL validation mode. ``True`` for default SSL check\n                  (:func:`ssl.create_default_context` is used),\n                  ``False`` for skip SSL certificate validation,\n                  :class:`aiohttp.Fingerprint` for fingerprint\n                  validation, :class:`ssl.SSLContext` for custom SSL\n                  certificate validation.\n\n                  Supersedes *verify_ssl*, *ssl_context* and\n                  *fingerprint* parameters.\n\n         .. versionadded:: 3.0\n\n   :param bool verify_ssl: perform SSL certificate validation for\n      *HTTPS* requests (enabled by default). May be disabled to\n      skip validation for sites with invalid certificates.\n\n      .. deprecated:: 2.3\n\n         Pass *verify_ssl* to ``ClientSession.get()`` etc.\n\n   :param bytes fingerprint: pass the SHA256 digest of the expected\n      certificate in DER format to verify that the certificate the\n      server presents matches. Useful for `certificate pinning\n      <https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning>`_.\n\n      Note: use of MD5 or SHA1 digests is insecure and deprecated.\n\n      .. deprecated:: 2.3\n\n         Pass *verify_ssl* to ``ClientSession.get()`` etc.\n\n   :param bool use_dns_cache: use internal cache for DNS lookups, ``True``\n      by default.\n\n      Enabling an option *may* speedup connection\n      establishing a bit but may introduce some\n      *side effects* also.\n\n   :param int ttl_dns_cache: expire after some seconds the DNS entries, ``None``\n      means cached forever. By default 10 seconds (optional).\n\n      In some environments the IP addresses related to a specific HOST can\n      change after a specific time. Use this option to keep the DNS cache\n      updated refreshing each entry after N seconds.\n\n   :param int limit: total number simultaneous connections. If *limit* is\n                     ``0`` the connector has no limit (default: 100).\n\n   :param int limit_per_host: limit simultaneous connections to the same\n      endpoint.  Endpoints are the same if they are\n      have equal ``(host, port, is_ssl)`` triple.\n      If *limit* is ``0`` the connector has no limit (default: 0).\n\n   :param aiohttp.abc.AbstractResolver resolver: custom resolver\n      instance to use.  ``aiohttp.DefaultResolver`` by\n      default (asynchronous if ``aiodns>=1.1`` is installed).\n\n      Custom resolvers allow to resolve hostnames differently than the\n      way the host is configured.\n\n      The resolver is ``aiohttp.ThreadedResolver`` by default,\n      asynchronous version is pretty robust but might fail in\n      very rare cases.\n\n   :param int family: TCP socket family, both IPv4 and IPv6 by default.\n                      For *IPv4* only use :data:`socket.AF_INET`,\n                      for  *IPv6* only -- :data:`socket.AF_INET6`.\n\n                      *family* is ``0`` by default, that means both\n                      IPv4 and IPv6 are accepted. To specify only\n                      concrete version please pass\n                      :data:`socket.AF_INET` or\n                      :data:`socket.AF_INET6` explicitly.\n\n   :param ssl.SSLContext ssl_context: SSL context used for processing\n      *HTTPS* requests (optional).\n\n      *ssl_context* may be used for configuring certification\n      authority channel, supported SSL options etc.\n\n   :param tuple local_addr: tuple of ``(local_host, local_port)`` used to bind\n      socket locally if specified.\n\n   :param bool force_close: close underlying sockets after\n                            connection releasing (optional).\n\n   :param bool enable_cleanup_closed: Some ssl servers do not properly complete\n      SSL shutdown process, in that case asyncio leaks SSL connections.\n      If this parameter is set to True, aiohttp additionally aborts underlining\n      transport after 2 seconds. It is off by default.\n\n   :param float happy_eyeballs_delay: The amount of time in seconds to wait for a\n      connection attempt to complete, before starting the next attempt in parallel.\n      This is the “Connection Attempt Delay” as defined in RFC 8305. To disable\n      Happy Eyeballs, set this to ``None``. The default value recommended by the\n      RFC is 0.25 (250 milliseconds).\n\n        .. versionadded:: 3.10\n\n   :param int interleave: controls address reordering when a host name resolves\n      to multiple IP addresses. If ``0`` or unspecified, no reordering is done, and\n      addresses are tried in the order returned by the resolver. If a positive\n      integer is specified, the addresses are interleaved by address family, and\n      the given integer is interpreted as “First Address Family Count” as defined\n      in RFC 8305. The default is ``0`` if happy_eyeballs_delay is not specified, and\n      ``1`` if it is.\n\n        .. versionadded:: 3.10\n\n   .. attribute:: family\n\n      *TCP* socket family e.g. :data:`socket.AF_INET` or\n      :data:`socket.AF_INET6`\n\n      Read-only property.\n\n   .. attribute:: dns_cache\n\n      Use quick lookup in internal *DNS* cache for host names if ``True``.\n\n      Read-only :class:`bool` property.\n\n   .. attribute:: cached_hosts\n\n      The cache of resolved hosts if :attr:`dns_cache` is enabled.\n\n      Read-only :class:`types.MappingProxyType` property.\n\n   .. method:: clear_dns_cache(self, host=None, port=None)\n\n      Clear internal *DNS* cache.\n\n      Remove specific entry if both *host* and *port* are specified,\n      clear all cache otherwise.\n\n\n.. class:: UnixConnector(path, *, conn_timeout=None, \\\n                         keepalive_timeout=30, limit=100, \\\n                         force_close=False, loop=None)\n\n   Unix socket connector.\n\n   Use :class:`UnixConnector` for sending *HTTP/HTTPS* requests\n   through *UNIX Sockets* as underlying transport.\n\n   UNIX sockets are handy for writing tests and making very fast\n   connections between processes on the same host.\n\n   :class:`UnixConnector` is inherited from :class:`BaseConnector`.\n\n    Usage::\n\n       conn = UnixConnector(path='/path/to/socket')\n       session = ClientSession(connector=conn)\n       async with session.get('http://python.org') as resp:\n           ...\n\n   Constructor accepts all parameters suitable for\n   :class:`BaseConnector` plus UNIX-specific one:\n\n   :param str path: Unix socket path\n\n\n   .. attribute:: path\n\n      Path to *UNIX socket*, read-only :class:`str` property.\n\n\n.. class:: Connection\n\n   Encapsulates single connection in connector object.\n\n   End user should never create :class:`Connection` instances manually\n   but get it by :meth:`BaseConnector.connect` coroutine.\n\n   .. attribute:: closed\n\n      :class:`bool` read-only property, ``True`` if connection was\n      closed, released or detached.\n\n   .. attribute:: loop\n\n      Event loop used for connection\n\n      .. deprecated:: 3.5\n\n   .. attribute:: transport\n\n      Connection transport\n\n   .. method:: close()\n\n      Close connection with forcibly closing underlying socket.\n\n   .. method:: release()\n\n      Release connection back to connector.\n\n      Underlying socket is not closed, the connection may be reused\n      later if timeout (30 seconds by default) for connection was not\n      expired.\n\n\nResponse object\n---------------\n\n.. class:: ClientResponse\n\n   Client response returned by :meth:`aiohttp.ClientSession.request` and family.\n\n   User never creates the instance of ClientResponse class but gets it\n   from API calls.\n\n   :class:`ClientResponse` supports async context manager protocol, e.g.::\n\n       resp = await client_session.get(url)\n       async with resp:\n           assert resp.status == 200\n\n   After exiting from ``async with`` block response object will be\n   *released* (see :meth:`release` method).\n\n   .. attribute:: version\n\n      Response's version, :class:`~aiohttp.protocol.HttpVersion` instance.\n\n   .. attribute:: status\n\n      HTTP status code of response (:class:`int`), e.g. ``200``.\n\n   .. attribute:: reason\n\n      HTTP status reason of response (:class:`str`), e.g. ``\"OK\"``.\n\n   .. attribute:: ok\n\n      Boolean representation of HTTP status code (:class:`bool`).\n      ``True`` if ``status`` is less than ``400``; otherwise, ``False``.\n\n   .. attribute:: method\n\n      Request's method (:class:`str`).\n\n   .. attribute:: url\n\n      URL of request (:class:`~yarl.URL`).\n\n   .. attribute:: real_url\n\n      Unmodified URL of request with URL fragment unstripped (:class:`~yarl.URL`).\n\n      .. versionadded:: 3.2\n\n   .. attribute:: connection\n\n      :class:`Connection` used for handling response.\n\n   .. attribute:: content\n\n      Payload stream, which contains response's BODY (:class:`StreamReader`).\n      It supports various reading methods depending on the expected format.\n      When chunked transfer encoding is used by the server, allows retrieving\n      the actual http chunks.\n\n      Reading from the stream may raise\n      :exc:`aiohttp.ClientPayloadError` if the response object is\n      closed before response receives all data or in case if any\n      transfer encoding related errors like malformed chunked\n      encoding of broken compression data.\n\n   .. attribute:: cookies\n\n      HTTP cookies of response (*Set-Cookie* HTTP header,\n      :class:`~http.cookies.SimpleCookie`).\n\n   .. attribute:: headers\n\n      A case-insensitive multidict proxy with HTTP headers of\n      response, :class:`~multidict.CIMultiDictProxy`.\n\n   .. attribute:: raw_headers\n\n      Unmodified HTTP headers of response as unconverted bytes, a sequence of\n      ``(key, value)`` pairs.\n\n   .. attribute:: links\n\n      Link HTTP header parsed into a :class:`~multidict.MultiDictProxy`.\n\n      For each link, key is link param `rel` when it exists, or link url as\n      :class:`str` otherwise, and value is :class:`~multidict.MultiDictProxy`\n      of link params and url at key `url` as :class:`~yarl.URL` instance.\n\n      .. versionadded:: 3.2\n\n   .. attribute:: content_type\n\n      Read-only property with *content* part of *Content-Type* header.\n\n      .. note::\n\n         Returns value is ``'application/octet-stream'`` if no\n         Content-Type header present in HTTP headers according to\n         :rfc:`2616`. To make sure Content-Type header is not present in\n         the server reply, use :attr:`headers` or :attr:`raw_headers`, e.g.\n         ``'CONTENT-TYPE' not in resp.headers``.\n\n   .. attribute:: charset\n\n      Read-only property that specifies the *encoding* for the request's BODY.\n\n      The value is parsed from the *Content-Type* HTTP header.\n\n      Returns :class:`str` like ``'utf-8'`` or ``None`` if no *Content-Type*\n      header present in HTTP headers or it has no charset information.\n\n   .. attribute:: content_disposition\n\n      Read-only property that specified the *Content-Disposition* HTTP header.\n\n      Instance of :class:`ContentDisposition` or ``None`` if no *Content-Disposition*\n      header present in HTTP headers.\n\n   .. attribute:: history\n\n      A :class:`~collections.abc.Sequence` of :class:`ClientResponse`\n      objects of preceding requests (earliest request first) if there were\n      redirects, an empty sequence otherwise.\n\n   .. method:: close()\n\n      Close response and underlying connection.\n\n      For :term:`keep-alive` support see :meth:`release`.\n\n   .. method:: read()\n      :async:\n\n      Read the whole response's body as :class:`bytes`.\n\n      Close underlying connection if data reading gets an error,\n      release connection otherwise.\n\n      Raise an :exc:`aiohttp.ClientResponseError` if the data can't\n      be read.\n\n      :return bytes: read *BODY*.\n\n      .. seealso:: :meth:`close`, :meth:`release`.\n\n   .. method:: release()\n\n      It is not required to call `release` on the response\n      object. When the client fully receives the payload, the\n      underlying connection automatically returns back to pool. If the\n      payload is not fully read, the connection is closed\n\n   .. method:: raise_for_status()\n\n      Raise an :exc:`aiohttp.ClientResponseError` if the response\n      status is 400 or higher.\n\n      Do nothing for success responses (less than 400).\n\n   .. method:: text(encoding=None)\n      :async:\n\n      Read response's body and return decoded :class:`str` using\n      specified *encoding* parameter.\n\n      If *encoding* is ``None`` content encoding is determined from the\n      Content-Type header, or using the ``fallback_charset_resolver`` function.\n\n      Close underlying connection if data reading gets an error,\n      release connection otherwise.\n\n      :param str encoding: text encoding used for *BODY* decoding, or\n                           ``None`` for encoding autodetection\n                           (default).\n\n\n      :raises: :exc:`UnicodeDecodeError` if decoding fails. See also\n               :meth:`get_encoding`.\n\n      :return str: decoded *BODY*\n\n   .. method:: json(*, encoding=None, loads=json.loads, \\\n                      content_type='application/json')\n      :async:\n\n      Read response's body as *JSON*, return :class:`dict` using\n      specified *encoding* and *loader*. If data is not still available\n      a ``read`` call will be done.\n\n      If response's `content-type` does not match `content_type` parameter\n      :exc:`aiohttp.ContentTypeError` get raised.\n      To disable content type check pass ``None`` value.\n\n      :param str encoding: text encoding used for *BODY* decoding, or\n                           ``None`` for encoding autodetection\n                           (default).\n\n                           By the standard JSON encoding should be\n                           ``UTF-8`` but practice beats purity: some\n                           servers return non-UTF\n                           responses. Autodetection works pretty fine\n                           anyway.\n\n      :param collections.abc.Callable loads: :term:`callable` used for loading *JSON*\n                             data, :func:`json.loads` by default.\n\n      :param str content_type: specify response's content-type, if content type\n         does not match raise :exc:`aiohttp.ClientResponseError`.\n         To disable `content-type` check, pass ``None`` as value.\n         (default: `application/json`).\n\n      :return: *BODY* as *JSON* data parsed by *loads* parameter or\n               ``None`` if *BODY* is empty or contains white-spaces only.\n\n   .. attribute:: request_info\n\n       A namedtuple with request URL and headers from :class:`~aiohttp.ClientRequest`\n       object, :class:`aiohttp.RequestInfo` instance.\n\n   .. method:: get_encoding()\n\n      Retrieve content encoding using ``charset`` info in ``Content-Type`` HTTP header.\n      If no charset is present or the charset is not understood by Python, the\n      ``fallback_charset_resolver`` function associated with the ``ClientSession`` is called.\n\n      .. versionadded:: 3.0\n\n\nClientWebSocketResponse\n-----------------------\n\nTo connect to a websocket server :func:`aiohttp.ws_connect` or\n:meth:`aiohttp.ClientSession.ws_connect` coroutines should be used, do\nnot create an instance of class :class:`ClientWebSocketResponse`\nmanually.\n\n.. class:: ClientWebSocketResponse()\n\n   Class for handling client-side websockets.\n\n   .. attribute:: closed\n\n      Read-only property, ``True`` if :meth:`close` has been called or\n      :const:`~aiohttp.WSMsgType.CLOSE` message has been received from peer.\n\n   .. attribute:: protocol\n\n      Websocket *subprotocol* chosen after :meth:`start` call.\n\n      May be ``None`` if server and client protocols are\n      not overlapping.\n\n   .. method:: get_extra_info(name, default=None)\n\n      Reads optional extra information from the connection's transport.\n      If no value associated with ``name`` is found, ``default`` is returned.\n\n      See :meth:`asyncio.BaseTransport.get_extra_info`\n\n      :param str name: The key to look up in the transport extra information.\n\n      :param default: Default value to be used when no value for ``name`` is\n                      found (default is ``None``).\n\n   .. method:: exception()\n\n      Returns exception if any occurs or returns None.\n\n   .. method:: ping(message=b'')\n      :async:\n\n      Send :const:`~aiohttp.WSMsgType.PING` to peer.\n\n      :param message: optional payload of *ping* message,\n                      :class:`str` (converted to *UTF-8* encoded bytes)\n                      or :class:`bytes`.\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`\n\n   .. method:: pong(message=b'')\n      :async:\n\n      Send :const:`~aiohttp.WSMsgType.PONG` to peer.\n\n      :param message: optional payload of *pong* message,\n                      :class:`str` (converted to *UTF-8* encoded bytes)\n                      or :class:`bytes`.\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`\n\n   .. method:: send_str(data, compress=None)\n      :async:\n\n      Send *data* to peer as :const:`~aiohttp.WSMsgType.TEXT` message.\n\n      :param str data: data to send.\n\n      :param int compress: sets specific level of compression for\n                           single message,\n                           ``None`` for not overriding per-socket setting.\n\n      :raise TypeError: if data is not :class:`str`\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`,\n         *compress* parameter added.\n\n   .. method:: send_bytes(data, compress=None)\n      :async:\n\n      Send *data* to peer as :const:`~aiohttp.WSMsgType.BINARY` message.\n\n      :param data: data to send.\n\n      :param int compress: sets specific level of compression for\n                           single message,\n                           ``None`` for not overriding per-socket setting.\n\n      :raise TypeError: if data is not :class:`bytes`,\n                        :class:`bytearray` or :class:`memoryview`.\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`,\n         *compress* parameter added.\n\n   .. method:: send_json(data, compress=None, *, dumps=json.dumps)\n      :async:\n\n      Send *data* to peer as JSON string.\n\n      :param data: data to send.\n\n      :param int compress: sets specific level of compression for\n                           single message,\n                           ``None`` for not overriding per-socket setting.\n\n      :param collections.abc.Callable dumps: any :term:`callable` that accepts an object and\n                             returns a JSON string\n                             (:func:`json.dumps` by default).\n\n      :raise RuntimeError: if connection is not started or closing\n\n      :raise ValueError: if data is not serializable object\n\n      :raise TypeError: if value returned by ``dumps(data)`` is not\n                        :class:`str`\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`,\n         *compress* parameter added.\n\n   .. method:: close(*, code=WSCloseCode.OK, message=b'')\n      :async:\n\n      A :ref:`coroutine<coroutine>` that initiates closing handshake by sending\n      :const:`~aiohttp.WSMsgType.CLOSE` message. It waits for\n      close response from server. To add a timeout to `close()` call\n      just wrap the call with `asyncio.wait()` or `asyncio.wait_for()`.\n\n      :param int code: closing code. See also :class:`~aiohttp.WSCloseCode`.\n\n      :param message: optional payload of *close* message,\n         :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`.\n\n   .. method:: receive()\n      :async:\n\n      A :ref:`coroutine<coroutine>` that waits upcoming *data*\n      message from peer and returns it.\n\n      The coroutine implicitly handles\n      :const:`~aiohttp.WSMsgType.PING`,\n      :const:`~aiohttp.WSMsgType.PONG` and\n      :const:`~aiohttp.WSMsgType.CLOSE` without returning the\n      message.\n\n      It process *ping-pong game* and performs *closing handshake* internally.\n\n      :return: :class:`~aiohttp.WSMessage`\n\n   .. method:: receive_str()\n      :async:\n\n      A :ref:`coroutine<coroutine>` that calls :meth:`receive` but\n      also asserts the message type is\n      :const:`~aiohttp.WSMsgType.TEXT`.\n\n      :return str: peer's message content.\n\n      :raise TypeError: if message is :const:`~aiohttp.WSMsgType.BINARY`.\n\n   .. method:: receive_bytes()\n      :async:\n\n      A :ref:`coroutine<coroutine>` that calls :meth:`receive` but\n      also asserts the message type is\n      :const:`~aiohttp.WSMsgType.BINARY`.\n\n      :return bytes: peer's message content.\n\n      :raise TypeError: if message is :const:`~aiohttp.WSMsgType.TEXT`.\n\n   .. method:: receive_json(*, loads=json.loads)\n      :async:\n\n      A :ref:`coroutine<coroutine>` that calls :meth:`receive_str` and loads\n      the JSON string to a Python dict.\n\n      :param collections.abc.Callable loads: any :term:`callable` that accepts\n                              :class:`str` and returns :class:`dict`\n                              with parsed JSON (:func:`json.loads` by\n                              default).\n\n      :return dict: loaded JSON content\n\n      :raise TypeError: if message is :const:`~aiohttp.WSMsgType.BINARY`.\n      :raise ValueError: if message is not valid JSON.\n\n\nUtilities\n---------\n\n\n.. class:: ClientTimeout(*, total=None, connect=None, \\\n                         sock_connect=None, sock_read=None)\n\n   A data class for client timeout settings.\n\n   See :ref:`aiohttp-client-timeouts` for usage examples.\n\n   .. attribute:: total\n\n      Total number of seconds for the whole request.\n\n      :class:`float`, ``None`` by default.\n\n   .. attribute:: connect\n\n      Maximal number of seconds for acquiring a connection from pool.  The time\n      consists connection establishment for a new connection or\n      waiting for a free connection from a pool if pool connection\n      limits are exceeded.\n\n      For pure socket connection establishment time use\n      :attr:`sock_connect`.\n\n      :class:`float`, ``None`` by default.\n\n   .. attribute:: sock_connect\n\n      Maximal number of seconds for connecting to a peer for a new connection, not\n      given from a pool.  See also :attr:`connect`.\n\n      :class:`float`, ``None`` by default.\n\n   .. attribute:: sock_read\n\n      Maximal number of seconds for reading a portion of data from a peer.\n\n      :class:`float`, ``None`` by default.\n\n   .. versionadded:: 3.3\n\n\n   .. note::\n\n      Timeouts of 5 seconds or more are rounded for scheduling on the next\n      second boundary (an absolute time where microseconds part is zero) for the\n      sake of performance.\n\n      E.g., assume a timeout is ``10``, absolute time when timeout should expire\n      is ``loop.time() + 5``, and it points to ``12345.67 + 10`` which is equal\n      to ``12355.67``.\n\n      The absolute time for the timeout cancellation is ``12356``.\n\n      It leads to grouping all close scheduled timeout expirations to exactly\n      the same time to reduce amount of loop wakeups.\n\n      .. versionchanged:: 3.7\n\n         Rounding to the next seconds boundary is disabled for timeouts smaller\n         than 5 seconds for the sake of easy debugging.\n\n         In turn, tiny timeouts can lead to significant performance degradation\n         on production environment.\n\n\n.. class:: ETag(name, is_weak=False)\n\n   Represents `ETag` identifier.\n\n   .. attribute:: value\n\n      Value of corresponding etag without quotes.\n\n   .. attribute:: is_weak\n\n      Flag indicates that etag is weak (has `W/` prefix).\n\n   .. versionadded:: 3.8\n\n\n.. class:: RequestInfo()\n\n   A data class with request URL and headers from :class:`~aiohttp.ClientRequest`\n   object, available as :attr:`ClientResponse.request_info` attribute.\n\n   .. attribute:: url\n\n      Requested *url*, :class:`yarl.URL` instance.\n\n   .. attribute:: method\n\n      Request HTTP method like ``'GET'`` or ``'POST'``, :class:`str`.\n\n   .. attribute:: headers\n\n      HTTP headers for request, :class:`multidict.CIMultiDict` instance.\n\n   .. attribute:: real_url\n\n      Requested *url* with URL fragment unstripped, :class:`yarl.URL` instance.\n\n      .. versionadded:: 3.2\n\n\n.. class:: BasicAuth(login, password='', encoding='latin1')\n\n   HTTP basic authentication helper.\n\n   :param str login: login\n   :param str password: password\n   :param str encoding: encoding (``'latin1'`` by default)\n\n\n   Should be used for specifying authorization data in client API,\n   e.g. *auth* parameter for :meth:`ClientSession.request() <aiohttp.ClientSession.request>`.\n\n\n   .. classmethod:: decode(auth_header, encoding='latin1')\n\n      Decode HTTP basic authentication credentials.\n\n      :param str auth_header:  The ``Authorization`` header to decode.\n      :param str encoding: (optional) encoding ('latin1' by default)\n\n      :return:  decoded authentication data, :class:`BasicAuth`.\n\n   .. classmethod:: from_url(url)\n\n      Constructed credentials info from url's *user* and *password*\n      parts.\n\n      :return: credentials data, :class:`BasicAuth` or ``None`` is\n                credentials are not provided.\n\n      .. versionadded:: 2.3\n\n   .. method:: encode()\n\n      Encode credentials into string suitable for ``Authorization``\n      header etc.\n\n      :return: encoded authentication data, :class:`str`.\n\n\n.. class:: CookieJar(*, unsafe=False, quote_cookie=True, treat_as_secure_origin = [])\n\n   The cookie jar instance is available as :attr:`ClientSession.cookie_jar`.\n\n   The jar contains :class:`~http.cookies.Morsel` items for storing\n   internal cookie data.\n\n   API provides a count of saved cookies::\n\n       len(session.cookie_jar)\n\n   These cookies may be iterated over::\n\n       for cookie in session.cookie_jar:\n           print(cookie.key)\n           print(cookie[\"domain\"])\n\n   The class implements :class:`collections.abc.Iterable`,\n   :class:`collections.abc.Sized` and\n   :class:`aiohttp.abc.AbstractCookieJar` interfaces.\n\n   Implements cookie storage adhering to RFC 6265.\n\n   :param bool unsafe: (optional) Whether to accept cookies from IPs.\n\n   :param bool quote_cookie: (optional) Whether to quote cookies according to\n                             :rfc:`2109`.  Some backend systems\n                             (not compatible with RFC mentioned above)\n                             does not support quoted cookies.\n\n      .. versionadded:: 3.7\n\n   :param treat_as_secure_origin: (optional) Mark origins as secure\n                                  for cookies marked as Secured. Possible types are\n\n                                  Possible types are:\n\n                                  - :class:`tuple` or :class:`list` of\n                                    :class:`str` or :class:`yarl.URL`\n                                  - :class:`str`\n                                  - :class:`yarl.URL`\n\n      .. versionadded:: 3.8\n\n   .. method:: update_cookies(cookies, response_url=None)\n\n      Update cookies returned by server in ``Set-Cookie`` header.\n\n      :param cookies: a :class:`collections.abc.Mapping`\n         (e.g. :class:`dict`, :class:`~http.cookies.SimpleCookie`) or\n         *iterable* of *pairs* with cookies returned by server's\n         response.\n\n      :param ~yarl.URL response_url: URL of response, ``None`` for *shared\n         cookies*.  Regular cookies are coupled with server's URL and\n         are sent only to this server, shared ones are sent in every\n         client request.\n\n   .. method:: filter_cookies(request_url)\n\n      Return jar's cookies acceptable for URL and available in\n      ``Cookie`` header for sending client requests for given URL.\n\n      :param ~yarl.URL response_url: request's URL for which cookies are asked.\n\n      :return: :class:`http.cookies.SimpleCookie` with filtered\n         cookies for given URL.\n\n   .. method:: save(file_path)\n\n      Write a pickled representation of cookies into the file\n      at provided path.\n\n      :param file_path: Path to file where cookies will be serialized,\n          :class:`str` or :class:`pathlib.Path` instance.\n\n   .. method:: load(file_path)\n\n      Load a pickled representation of cookies from the file\n      at provided path.\n\n      :param file_path: Path to file from where cookies will be\n           imported, :class:`str` or :class:`pathlib.Path` instance.\n\n   .. method:: clear(predicate=None)\n\n      Removes all cookies from the jar if the predicate is ``None``. Otherwise remove only those :class:`~http.cookies.Morsel` that ``predicate(morsel)`` returns ``True``.\n\n      :param predicate: callable that gets :class:`~http.cookies.Morsel` as a parameter and returns ``True`` if this :class:`~http.cookies.Morsel` must be deleted from the jar.\n\n          .. versionadded:: 4.0\n\n   .. method:: clear_domain(domain)\n\n      Remove all cookies from the jar that belongs to the specified domain or its subdomains.\n\n      :param str domain: domain for which cookies must be deleted from the jar.\n\n      .. versionadded:: 4.0\n\n\n.. class:: DummyCookieJar(*, loop=None)\n\n   Dummy cookie jar which does not store cookies but ignores them.\n\n   Could be useful e.g. for web crawlers to iterate over Internet\n   without blowing up with saved cookies information.\n\n   To install dummy cookie jar pass it into session instance::\n\n      jar = aiohttp.DummyCookieJar()\n      session = aiohttp.ClientSession(cookie_jar=DummyCookieJar())\n\n\n.. class:: Fingerprint(digest)\n\n   Fingerprint helper for checking SSL certificates by *SHA256* digest.\n\n   :param bytes digest: *SHA256* digest for certificate in DER-encoded\n                        binary form (see\n                        :meth:`ssl.SSLSocket.getpeercert`).\n\n   To check fingerprint pass the object into :meth:`ClientSession.get`\n   call, e.g.::\n\n      import hashlib\n\n      with open(path_to_cert, 'rb') as f:\n          digest = hashlib.sha256(f.read()).digest()\n\n      await session.get(url, ssl=aiohttp.Fingerprint(digest))\n\n   .. versionadded:: 3.0\n\nFormData\n^^^^^^^^\n\nA :class:`FormData` object contains the form data and also handles\nencoding it into a body that is either ``multipart/form-data`` or\n``application/x-www-form-urlencoded``. ``multipart/form-data`` is\nused if at least one field is an :class:`io.IOBase` object or was\nadded with at least one optional argument to :meth:`add_field<aiohttp.FormData.add_field>`\n(``content_type``, ``filename``, or ``content_transfer_encoding``).\nOtherwise, ``application/x-www-form-urlencoded`` is used.\n\n:class:`FormData` instances are callable and return a :class:`aiohttp.payload.Payload`\non being called.\n\n.. class:: FormData(fields, quote_fields=True, charset=None)\n\n   Helper class for multipart/form-data and application/x-www-form-urlencoded body generation.\n\n   :param fields: A container for the key/value pairs of this form.\n\n                  Possible types are:\n\n                  - :class:`dict`\n                  - :class:`tuple` or :class:`list`\n                  - :class:`io.IOBase`, e.g. a file-like object\n                  - :class:`multidict.MultiDict` or :class:`multidict.MultiDictProxy`\n\n                  If it is a :class:`tuple` or :class:`list`, it must be a valid argument\n                  for :meth:`add_fields<aiohttp.FormData.add_fields>`.\n\n                  For :class:`dict`, :class:`multidict.MultiDict`, and :class:`multidict.MultiDictProxy`,\n                  the keys and values must be valid `name` and `value` arguments to\n                  :meth:`add_field<aiohttp.FormData.add_field>`, respectively.\n\n   .. method:: add_field(name, value, content_type=None, filename=None,\\\n                         content_transfer_encoding=None)\n\n      Add a field to the form.\n\n      :param str name: Name of the field\n\n      :param value: Value of the field\n\n                    Possible types are:\n\n                    - :class:`str`\n                    - :class:`bytes`, :class:`bytearray`, or :class:`memoryview`\n                    - :class:`io.IOBase`, e.g. a file-like object\n\n      :param str content_type: The field's content-type header (optional)\n\n      :param str filename: The field's filename (optional)\n\n                           If this is not set and ``value`` is a :class:`bytes`, :class:`bytearray`,\n                           or :class:`memoryview` object, the `name` argument is used as the filename\n                           unless ``content_transfer_encoding`` is specified.\n\n                           If ``filename`` is not set and ``value`` is an :class:`io.IOBase`\n                           object, the filename is extracted from the object if possible.\n\n      :param str content_transfer_encoding: The field's content-transfer-encoding\n                                            header (optional)\n\n   .. method:: add_fields(fields)\n\n      Add one or more fields to the form.\n\n      :param fields: An iterable containing:\n\n                     - :class:`io.IOBase`, e.g. a file-like object\n                     - :class:`multidict.MultiDict` or :class:`multidict.MultiDictProxy`\n                     - :class:`tuple` or :class:`list` of length two, containing a name-value pair\n\nClient exceptions\n-----------------\n\nException hierarchy has been significantly modified in version\n2.0. aiohttp defines only exceptions that covers connection handling\nand server response misbehaviors.  For developer specific mistakes,\naiohttp uses python standard exceptions like :exc:`ValueError` or\n:exc:`TypeError`.\n\nReading a response content may raise a :exc:`ClientPayloadError`\nexception. This exception indicates errors specific to the payload\nencoding. Such as invalid compressed data, malformed chunked-encoded\nchunks or not enough data that satisfy the content-length header.\n\nAll exceptions are available as members of *aiohttp* module.\n\n.. exception:: ClientError\n\n   Base class for all client specific exceptions.\n\n   Derived from :exc:`Exception`\n\n\n.. class:: ClientPayloadError\n\n   This exception can only be raised while reading the response\n   payload if one of these errors occurs:\n\n   1. invalid compression\n   2. malformed chunked encoding\n   3. not enough data that satisfy ``Content-Length`` HTTP header.\n\n   Derived from :exc:`ClientError`\n\n.. exception:: InvalidURL\n\n   URL used for fetching is malformed, e.g. it does not contain host\n   part.\n\n   Derived from :exc:`ClientError` and :exc:`ValueError`\n\n   .. attribute:: url\n\n      Invalid URL, :class:`yarl.URL` instance.\n\n    .. attribute:: description\n\n      Invalid URL description, :class:`str` instance or :data:`None`.\n\n.. exception:: InvalidUrlClientError\n\n   Base class for all errors related to client url.\n\n   Derived from :exc:`InvalidURL`\n\n.. exception:: RedirectClientError\n\n   Base class for all errors related to client redirects.\n\n   Derived from :exc:`ClientError`\n\n.. exception:: NonHttpUrlClientError\n\n   Base class for all errors related to non http client urls.\n\n   Derived from :exc:`ClientError`\n\n.. exception:: InvalidUrlRedirectClientError\n\n   Redirect URL is malformed, e.g. it does not contain host part.\n\n   Derived from :exc:`InvalidUrlClientError` and :exc:`RedirectClientError`\n\n.. exception:: NonHttpUrlRedirectClientError\n\n   Redirect URL does not contain http schema.\n\n   Derived from :exc:`RedirectClientError` and :exc:`NonHttpUrlClientError`\n\n\n.. class:: ContentDisposition\n\n    Represent Content-Disposition header\n\n    .. attribute:: type\n\n    A :class:`str` instance. Value of Content-Disposition header\n    itself, e.g. ``attachment``.\n\n    .. attribute:: filename\n\n    A :class:`str` instance. Content filename extracted from\n    parameters. May be ``None``.\n\n    .. attribute:: parameters\n\n    Read-only mapping contains all parameters.\n\nResponse errors\n^^^^^^^^^^^^^^^\n\n.. exception:: ClientResponseError\n\n   These exceptions could happen after we get response from server.\n\n   Derived from :exc:`ClientError`\n\n   .. attribute:: request_info\n\n      Instance of :class:`RequestInfo` object, contains information\n      about request.\n\n   .. attribute:: status\n\n      HTTP status code of response (:class:`int`), e.g. ``400``.\n\n   .. attribute:: message\n\n      Message of response (:class:`str`), e.g. ``\"OK\"``.\n\n   .. attribute:: headers\n\n      Headers in response, a list of pairs.\n\n   .. attribute:: history\n\n      History from failed response, if available, else empty tuple.\n\n      A :class:`tuple` of :class:`ClientResponse` objects used for\n      handle redirection responses.\n\n   .. attribute:: code\n\n      HTTP status code of response (:class:`int`), e.g. ``400``.\n\n      .. deprecated:: 3.1\n\n\n.. class:: ContentTypeError\n\n   Invalid content type.\n\n   Derived from :exc:`ClientResponseError`\n\n   .. versionadded:: 2.3\n\n\n.. class:: TooManyRedirects\n\n   Client was redirected too many times.\n\n   Maximum number of redirects can be configured by using\n   parameter ``max_redirects`` in :meth:`request<aiohttp.ClientSession.request>`.\n\n   Derived from :exc:`ClientResponseError`\n\n   .. versionadded:: 3.2\n\n\n.. class:: WSServerHandshakeError\n\n   Web socket server response error.\n\n   Derived from :exc:`ClientResponseError`\n\nConnection errors\n^^^^^^^^^^^^^^^^^\n\n.. class:: ClientConnectionError\n\n   These exceptions related to low-level connection problems.\n\n   Derived from :exc:`ClientError`\n\n.. class:: ClientOSError\n\n   Subset of connection errors that are initiated by an :exc:`OSError`\n   exception.\n\n   Derived from :exc:`ClientConnectionError` and :exc:`OSError`\n\n.. class:: ClientConnectorError\n\n   Connector related exceptions.\n\n   Derived from :exc:`ClientOSError`\n\n.. class:: ClientProxyConnectionError\n\n   Derived from :exc:`ClientConnectorError`\n\n.. class:: ClientSSLError\n\n   Derived from :exc:`ClientConnectorError`\n\n.. class:: ClientConnectorSSLError\n\n   Response ssl error.\n\n   Derived from :exc:`ClientSSLError` and :exc:`ssl.SSLError`\n\n.. class:: ClientConnectorCertificateError\n\n   Response certificate error.\n\n   Derived from :exc:`ClientSSLError` and :exc:`ssl.CertificateError`\n\n.. class:: UnixClientConnectorError\n\n   Derived from :exc:`ClientConnectorError`\n\n.. class:: ServerConnectionError\n\n   Derived from :exc:`ClientConnectionError`\n\n.. class:: ServerDisconnectedError\n\n   Server disconnected.\n\n   Derived from :exc:`~aiohttp.ServerConnectionError`\n\n   .. attribute:: message\n\n      Partially parsed HTTP message (optional).\n\n\n.. class:: ServerFingerprintMismatch\n\n   Server fingerprint mismatch.\n\n   Derived from :exc:`ServerConnectionError`\n\n.. class:: ServerTimeoutError\n\n   Server operation timeout: read timeout, etc.\n\n   Derived from :exc:`ServerConnectionError` and :exc:`asyncio.TimeoutError`\n\n.. class:: ConnectionTimeoutError\n\n   Connection timeout on request: e.g. read timeout.\n\n   Derived from :exc:`ServerTimeoutError`\n\n.. class:: SocketTimeoutError\n\n   Reading from socket timeout.\n\n   Derived from :exc:`ServerTimeoutError`\n\nHierarchy of exceptions\n^^^^^^^^^^^^^^^^^^^^^^^\n\n* :exc:`ClientError`\n\n  * :exc:`ClientConnectionError`\n\n    * :exc:`ClientOSError`\n\n      * :exc:`ClientConnectorError`\n\n        * :exc:`ClientProxyConnectionError`\n\n        * :exc:`ClientSSLError`\n\n          * :exc:`ClientConnectorCertificateError`\n\n          * :exc:`ClientConnectorSSLError`\n\n        * :exc:`UnixClientConnectorError`\n\n    * :exc:`ServerConnectionError`\n\n      * :exc:`ServerDisconnectedError`\n\n      * :exc:`ServerFingerprintMismatch`\n\n      * :exc:`ServerTimeoutError`\n\n        * :exc:`ConnectionTimeoutError`\n\n        * :exc:`SocketTimeoutError`\n\n  * :exc:`ClientPayloadError`\n\n  * :exc:`ClientResponseError`\n\n    * :exc:`~aiohttp.ClientHttpProxyError`\n\n    * :exc:`ContentTypeError`\n\n    * :exc:`TooManyRedirects`\n\n    * :exc:`WSServerHandshakeError`\n\n  * :exc:`InvalidURL`\n\n    * :exc:`InvalidUrlClientError`\n\n      * :exc:`InvalidUrlRedirectClientError`\n\n  * :exc:`NonHttpUrlClientError`\n\n    * :exc:`NonHttpUrlRedirectClientError`\n\n  * :exc:`RedirectClientError`\n\n    * :exc:`InvalidUrlRedirectClientError`\n\n    * :exc:`NonHttpUrlRedirectClientError`\n",
            "new_file_content": ".. _aiohttp-client-reference:\n\nClient Reference\n================\n\n.. currentmodule:: aiohttp\n\n\nClient Session\n--------------\n\nClient session is the recommended interface for making HTTP requests.\n\nSession encapsulates a *connection pool* (*connector* instance) and\nsupports keepalives by default. Unless you are connecting to a large,\nunknown number of different servers over the lifetime of your\napplication, it is suggested you use a single session for the\nlifetime of your application to benefit from connection pooling.\n\nUsage example::\n\n     import aiohttp\n     import asyncio\n\n     async def fetch(client):\n         async with client.get('http://python.org') as resp:\n             assert resp.status == 200\n             return await resp.text()\n\n     async def main():\n         async with aiohttp.ClientSession() as client:\n             html = await fetch(client)\n             print(html)\n\n     asyncio.run(main())\n\n\nThe client session supports the context manager protocol for self closing.\n\n.. class:: ClientSession(base_url=None, *, \\\n                         connector=None, cookies=None, \\\n                         headers=None, skip_auto_headers=None, \\\n                         auth=None, json_serialize=json.dumps, \\\n                         version=aiohttp.HttpVersion11, \\\n                         cookie_jar=None, read_timeout=None, \\\n                         conn_timeout=None, \\\n                         timeout=sentinel, \\\n                         raise_for_status=False, \\\n                         connector_owner=True, \\\n                         auto_decompress=True, \\\n                         read_bufsize=2**16, \\\n                         requote_redirect_url=True, \\\n                         trust_env=False, \\\n                         trace_configs=None, \\\n                         fallback_charset_resolver=lambda r, b: \"utf-8\")\n\n   The class for creating client sessions and making requests.\n\n\n   :param base_url: Base part of the URL (optional)\n      If set, it allows to skip the base part (https://docs.aiohttp.org) in\n      request calls. It must not include a path (as in\n      https://docs.aiohttp.org/en/stable).\n\n      .. versionadded:: 3.8\n\n   :param aiohttp.BaseConnector connector: BaseConnector\n      sub-class instance to support connection pooling.\n\n   :param loop: :ref:`event loop<asyncio-event-loop>` used for\n      processing HTTP requests.\n\n      If *loop* is ``None`` the constructor\n      borrows it from *connector* if specified.\n\n      :func:`asyncio.get_event_loop` is used for getting default event\n      loop otherwise.\n\n      .. deprecated:: 2.0\n\n   :param dict cookies: Cookies to send with the request (optional)\n\n   :param headers: HTTP Headers to send with every request (optional).\n\n                   May be either *iterable of key-value pairs* or\n                   :class:`~collections.abc.Mapping`\n                   (e.g. :class:`dict`,\n                   :class:`~multidict.CIMultiDict`).\n\n   :param skip_auto_headers: set of headers for which autogeneration\n      should be skipped.\n\n      *aiohttp* autogenerates headers like ``User-Agent`` or\n      ``Content-Type`` if these headers are not explicitly\n      passed. Using ``skip_auto_headers`` parameter allows to skip\n      that generation. Note that ``Content-Length`` autogeneration can't\n      be skipped.\n\n      Iterable of :class:`str` or :class:`~multidict.istr` (optional)\n\n   :param aiohttp.BasicAuth auth: an object that represents HTTP Basic\n                                  Authorization (optional). It will be included\n                                  with any request. However, if the\n                                  ``_base_url`` parameter is set, the request\n                                  URL's origin must match the base URL's origin;\n                                  otherwise, the default auth will not be\n                                  included.\n\n   :param version: supported HTTP version, ``HTTP 1.1`` by default.\n\n   :param cookie_jar: Cookie Jar, :class:`~aiohttp.abc.AbstractCookieJar` instance.\n\n      By default every session instance has own private cookie jar for\n      automatic cookies processing but user may redefine this behavior\n      by providing own jar implementation.\n\n      One example is not processing cookies at all when working in\n      proxy mode.\n\n      If no cookie processing is needed, a\n      :class:`aiohttp.DummyCookieJar` instance can be\n      provided.\n\n   :param collections.abc.Callable json_serialize: Json *serializer* callable.\n\n      By default :func:`json.dumps` function.\n\n   :param bool raise_for_status:\n\n      Automatically call :meth:`ClientResponse.raise_for_status()` for\n      each response, ``False`` by default.\n\n      This parameter can be overridden when making a request, e.g.::\n\n          client_session = aiohttp.ClientSession(raise_for_status=True)\n          resp = await client_session.get(url, raise_for_status=False)\n          async with resp:\n              assert resp.status == 200\n\n      Set the parameter to ``True`` if you need ``raise_for_status``\n      for most of cases but override ``raise_for_status`` for those\n      requests where you need to handle responses with status 400 or\n      higher.\n\n   :param timeout: a :class:`ClientTimeout` settings structure, 300 seconds (5min)\n        total timeout by default.\n\n      .. versionadded:: 3.3\n\n   :param float read_timeout: Request operations timeout. ``read_timeout`` is\n      cumulative for all request operations (request, redirects, responses,\n      data consuming). By default, the read timeout is 5*60 seconds.\n      Use ``None`` or ``0`` to disable timeout checks.\n\n      .. deprecated:: 3.3\n\n         Use ``timeout`` parameter instead.\n\n   :param float conn_timeout: timeout for connection establishing\n      (optional). Values ``0`` or ``None`` mean no timeout.\n\n      .. deprecated:: 3.3\n\n         Use ``timeout`` parameter instead.\n\n   :param bool connector_owner:\n\n      Close connector instance on session closing.\n\n      Setting the parameter to ``False`` allows to share\n      connection pool between sessions without sharing session state:\n      cookies etc.\n\n   :param bool auto_decompress: Automatically decompress response body (``True`` by default).\n\n      .. versionadded:: 2.3\n\n   :param int read_bufsize: Size of the read buffer (:attr:`ClientResponse.content`).\n                            64 KiB by default.\n\n      .. versionadded:: 3.7\n\n   :param bool trust_env: Trust environment settings for proxy configuration if the parameter\n      is ``True`` (``False`` by default). See :ref:`aiohttp-client-proxy-support` for\n      more information.\n\n      Get proxy credentials from ``~/.netrc`` file if present.\n\n      Get HTTP Basic Auth credentials from :file:`~/.netrc` file if present.\n\n      If :envvar:`NETRC` environment variable is set, read from file specified\n      there rather than from :file:`~/.netrc`.\n\n      .. seealso::\n\n         ``.netrc`` documentation: https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html\n\n      .. versionadded:: 2.3\n\n      .. versionchanged:: 3.0\n\n         Added support for ``~/.netrc`` file.\n\n      .. versionchanged:: 3.9\n\n         Added support for reading HTTP Basic Auth credentials from :file:`~/.netrc` file.\n\n   :param bool requote_redirect_url: Apply *URL requoting* for redirection URLs if\n                                     automatic redirection is enabled (``True`` by\n                                     default).\n\n      .. versionadded:: 3.5\n\n   :param trace_configs: A list of :class:`TraceConfig` instances used for client\n                         tracing.  ``None`` (default) is used for request tracing\n                         disabling.  See :ref:`aiohttp-client-tracing-reference` for\n                         more information.\n\n   :param Callable[[ClientResponse,bytes],str] fallback_charset_resolver:\n      A :term:`callable` that accepts a :class:`ClientResponse` and the\n      :class:`bytes` contents, and returns a :class:`str` which will be used as\n      the encoding parameter to :meth:`bytes.decode()`.\n\n      This function will be called when the charset is not known (e.g. not specified in the\n      Content-Type header). The default function simply defaults to ``utf-8``.\n\n      .. versionadded:: 3.8.6\n\n   .. attribute:: closed\n\n      ``True`` if the session has been closed, ``False`` otherwise.\n\n      A read-only property.\n\n   .. attribute:: connector\n\n      :class:`aiohttp.BaseConnector` derived instance used\n      for the session.\n\n      A read-only property.\n\n   .. attribute:: cookie_jar\n\n      The session cookies, :class:`~aiohttp.abc.AbstractCookieJar` instance.\n\n      Gives access to cookie jar's content and modifiers.\n\n      A read-only property.\n\n   .. attribute:: requote_redirect_url\n\n      aiohttp re quote's redirect urls by default, but some servers\n      require exact url from location header. To disable *re-quote* system\n      set :attr:`requote_redirect_url` attribute to ``False``.\n\n      .. versionadded:: 2.1\n\n      .. note:: This parameter affects all subsequent requests.\n\n      .. deprecated:: 3.5\n\n         The attribute modification is deprecated.\n\n   .. attribute:: loop\n\n      A loop instance used for session creation.\n\n      A read-only property.\n\n      .. deprecated:: 3.5\n\n   .. attribute:: timeout\n\n      Default client timeouts, :class:`ClientTimeout` instance.  The value can\n      be tuned by passing *timeout* parameter to :class:`ClientSession`\n      constructor.\n\n      .. versionadded:: 3.7\n\n   .. attribute:: headers\n\n      HTTP Headers that sent with every request\n\n      May be either *iterable of key-value pairs* or\n      :class:`~collections.abc.Mapping`\n      (e.g. :class:`dict`,\n      :class:`~multidict.CIMultiDict`).\n\n      .. versionadded:: 3.7\n\n   .. attribute:: skip_auto_headers\n\n      Set of headers for which autogeneration skipped.\n\n      :class:`frozenset` of :class:`str` or :class:`~multidict.istr` (optional)\n\n      .. versionadded:: 3.7\n\n   .. attribute:: auth\n\n      An object that represents HTTP Basic Authorization.\n\n      :class:`~aiohttp.BasicAuth` (optional)\n\n      .. versionadded:: 3.7\n\n   .. attribute:: json_serialize\n\n      Json serializer callable.\n\n      By default :func:`json.dumps` function.\n\n      .. versionadded:: 3.7\n\n   .. attribute:: connector_owner\n\n      Should connector be closed on session closing\n\n      :class:`bool` (optional)\n\n      .. versionadded:: 3.7\n\n   .. attribute:: raise_for_status\n\n      Should :meth:`ClientResponse.raise_for_status()` be called for each response\n\n      Either :class:`bool` or :class:`collections.abc.Callable`\n\n      .. versionadded:: 3.7\n\n   .. attribute:: auto_decompress\n\n      Should the body response be automatically decompressed\n\n      :class:`bool` default is ``True``\n\n      .. versionadded:: 3.7\n\n   .. attribute:: trust_env\n\n      Trust environment settings for proxy configuration\n      or ~/.netrc file if present. See :ref:`aiohttp-client-proxy-support` for\n      more information.\n\n      :class:`bool` default is ``False``\n\n      .. versionadded:: 3.7\n\n   .. attribute:: trace_config\n\n      A list of :class:`TraceConfig` instances used for client\n      tracing.  ``None`` (default) is used for request tracing\n      disabling.  See :ref:`aiohttp-client-tracing-reference` for more information.\n\n      .. versionadded:: 3.7\n\n   .. method:: request(method, url, *, params=None, data=None, json=None,\\\n                         cookies=None, headers=None, skip_auto_headers=None, \\\n                         auth=None, allow_redirects=True,\\\n                         max_redirects=10,\\\n                         compress=None, chunked=None, expect100=False, raise_for_status=None,\\\n                         read_until_eof=True, \\\n                         read_bufsize=None, \\\n                         proxy=None, proxy_auth=None,\\\n                         timeout=sentinel, ssl=True, \\\n                         verify_ssl=None, fingerprint=None, \\\n                         ssl_context=None, proxy_headers=None, \\\n                         server_hostname=None, auto_decompress=None)\n      :async:\n      :noindexentry:\n\n      Performs an asynchronous HTTP request. Returns a response object that\n      should be used as an async context manager.\n\n      :param str method: HTTP method\n\n      :param url: Request URL, :class:`~yarl.URL` or :class:`str` that will\n                  be encoded with :class:`~yarl.URL` (see :class:`~yarl.URL`\n                  to skip encoding).\n\n      :param params: Mapping, iterable of tuple of *key*/*value* pairs or\n                     string to be sent as parameters in the query\n                     string of the new request. Ignored for subsequent\n                     redirected requests (optional)\n\n                     Allowed values are:\n\n                     - :class:`collections.abc.Mapping` e.g. :class:`dict`,\n                       :class:`multidict.MultiDict` or\n                       :class:`multidict.MultiDictProxy`\n                     - :class:`collections.abc.Iterable` e.g. :class:`tuple` or\n                       :class:`list`\n                     - :class:`str` with preferably url-encoded content\n                       (**Warning:** content will not be encoded by *aiohttp*)\n\n      :param data: The data to send in the body of the request. This can be a\n                   :class:`FormData` object or anything that can be passed into\n                   :class:`FormData`, e.g. a dictionary, bytes, or file-like object.\n                   (optional)\n\n      :param json: Any json compatible python object\n                   (optional). *json* and *data* parameters could not\n                   be used at the same time.\n\n      :param dict cookies: HTTP Cookies to send with\n                           the request (optional)\n\n         Global session cookies and the explicitly set cookies will be merged\n         when sending the request.\n\n         .. versionadded:: 3.5\n\n      :param dict headers: HTTP Headers to send with\n                           the request (optional)\n\n      :param skip_auto_headers: set of headers for which autogeneration\n         should be skipped.\n\n         *aiohttp* autogenerates headers like ``User-Agent`` or\n         ``Content-Type`` if these headers are not explicitly\n         passed. Using ``skip_auto_headers`` parameter allows to skip\n         that generation.\n\n         Iterable of :class:`str` or :class:`~multidict.istr`\n         (optional)\n\n      :param aiohttp.BasicAuth auth: an object that represents HTTP\n                                     Basic Authorization (optional)\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``True`` by default (optional).\n\n      :param int max_redirects: Maximum number of redirects to follow.\n                                ``10`` by default.\n\n      :param bool compress: Set to ``True`` if request has to be compressed\n         with deflate encoding. If `compress` can not be combined\n         with a *Content-Encoding* and *Content-Length* headers.\n         ``None`` by default (optional).\n\n      :param int chunked: Enable chunked transfer encoding.\n         It is up to the developer\n         to decide how to chunk data streams. If chunking is enabled, aiohttp\n         encodes the provided chunks in the \"Transfer-encoding: chunked\" format.\n         If *chunked* is set, then the *Transfer-encoding* and *content-length*\n         headers are disallowed. ``None`` by default (optional).\n\n      :param bool expect100: Expect 100-continue response from server.\n                             ``False`` by default (optional).\n\n      :param bool raise_for_status: Automatically call :meth:`ClientResponse.raise_for_status()` for\n                                    response if set to ``True``.\n                                    If set to ``None`` value from ``ClientSession`` will be used.\n                                    ``None`` by default (optional).\n\n          .. versionadded:: 3.4\n\n      :param bool read_until_eof: Read response until EOF if response\n                                  does not have Content-Length header.\n                                  ``True`` by default (optional).\n\n      :param int read_bufsize: Size of the read buffer (:attr:`ClientResponse.content`).\n                              ``None`` by default,\n                              it means that the session global value is used.\n\n          .. versionadded:: 3.7\n\n      :param proxy: Proxy URL, :class:`str` or :class:`~yarl.URL` (optional)\n\n      :param aiohttp.BasicAuth proxy_auth: an object that represents proxy HTTP\n                                           Basic Authorization (optional)\n\n      :param int timeout: override the session's timeout.\n\n         .. versionchanged:: 3.3\n\n            The parameter is :class:`ClientTimeout` instance,\n            :class:`float` is still supported for sake of backward\n            compatibility.\n\n            If :class:`float` is passed it is a *total* timeout (in seconds).\n\n      :param ssl: SSL validation mode. ``True`` for default SSL check\n                  (:func:`ssl.create_default_context` is used),\n                  ``False`` for skip SSL certificate validation,\n                  :class:`aiohttp.Fingerprint` for fingerprint\n                  validation, :class:`ssl.SSLContext` for custom SSL\n                  certificate validation.\n\n                  Supersedes *verify_ssl*, *ssl_context* and\n                  *fingerprint* parameters.\n\n         .. versionadded:: 3.0\n\n      :param bool verify_ssl: Perform SSL certificate validation for\n         *HTTPS* requests (enabled by default). May be disabled to\n         skip validation for sites with invalid certificates.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=False``\n\n      :param bytes fingerprint: Pass the SHA256 digest of the expected\n         certificate in DER format to verify that the certificate the\n         server presents matches. Useful for `certificate pinning\n         <https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning>`_.\n\n         Warning: use of MD5 or SHA1 digests is insecure and removed.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=aiohttp.Fingerprint(digest)``\n\n      :param str server_hostname: Sets or overrides the host name that the\n         target server’s certificate will be matched against.\n\n         See :py:meth:`asyncio.loop.create_connection` for more information.\n\n         .. versionadded:: 3.9\n\n      :param ssl.SSLContext ssl_context: ssl context used for processing\n         *HTTPS* requests (optional).\n\n         *ssl_context* may be used for configuring certification\n         authority channel, supported SSL options etc.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=ssl_context``\n\n      :param collections.abc.Mapping proxy_headers: HTTP headers to send to the proxy if the\n         parameter proxy has been provided.\n\n         .. versionadded:: 2.3\n\n      :param trace_request_ctx: Object used to give as a kw param for each new\n        :class:`TraceConfig` object instantiated,\n        used to give information to the\n        tracers that is only available at request time.\n\n         .. versionadded:: 3.0\n\n      :param bool auto_decompress: Automatically decompress response body.\n         Overrides :attr:`ClientSession.auto_decompress`.\n         May be used to enable/disable auto decompression on a per-request basis.\n\n      :return ClientResponse: a :class:`client response <ClientResponse>`\n         object.\n\n   .. method:: get(url, *, allow_redirects=True, **kwargs)\n      :async:\n\n      Perform a ``GET`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``True`` by default (optional).\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: post(url, *, data=None, **kwargs)\n      :async:\n\n      Perform a ``POST`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param data: Data to send in the body of the request; see\n                   :meth:`request<aiohttp.ClientSession.request>`\n                   for details (optional)\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: put(url, *, data=None, **kwargs)\n      :async:\n\n      Perform a ``PUT`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param data: Data to send in the body of the request; see\n                   :meth:`request<aiohttp.ClientSession.request>`\n                   for details (optional)\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: delete(url, **kwargs)\n      :async:\n\n      Perform a ``DELETE`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: head(url, *, allow_redirects=False, **kwargs)\n      :async:\n\n      Perform a ``HEAD`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``False`` by default (optional).\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: options(url, *, allow_redirects=True, **kwargs)\n      :async:\n\n      Perform an ``OPTIONS`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                   ``True`` by default (optional).\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: patch(url, *, data=None, **kwargs)\n      :async:\n\n      Perform a ``PATCH`` request. Returns an async context manager.\n\n      In order to modify inner\n      :meth:`request<aiohttp.ClientSession.request>`\n      parameters, provide `kwargs`.\n\n      :param url: Request URL, :class:`str` or :class:`~yarl.URL`\n\n      :param data: Data to send in the body of the request; see\n                   :meth:`request<aiohttp.ClientSession.request>`\n                   for details (optional)\n\n      :return ClientResponse: a :class:`client response\n                              <ClientResponse>` object.\n\n   .. method:: ws_connect(url, *, method='GET', \\\n                            protocols=(), timeout=10.0,\\\n                            receive_timeout=None,\\\n                            auth=None,\\\n                            autoclose=True,\\\n                            autoping=True,\\\n                            heartbeat=None,\\\n                            origin=None, \\\n                            params=None, \\\n                            headers=None, \\\n                            proxy=None, proxy_auth=None, ssl=True, \\\n                            verify_ssl=None, fingerprint=None, \\\n                            ssl_context=None, proxy_headers=None, \\\n                            compress=0, max_msg_size=4194304)\n      :async:\n\n      Create a websocket connection. Returns a\n      :class:`ClientWebSocketResponse` async context manager object.\n\n      :param url: Websocket server url, :class:`~yarl.URL` or :class:`str` that\n                  will be encoded with :class:`~yarl.URL` (see :class:`~yarl.URL`\n                  to skip encoding).\n\n      :param tuple protocols: Websocket protocols\n\n      :param float timeout: Timeout for websocket to close. ``10`` seconds\n                            by default\n\n      :param float receive_timeout: Timeout for websocket to receive\n                                    complete message.  ``None`` (unlimited)\n                                    seconds by default\n\n      :param aiohttp.BasicAuth auth: an object that represents HTTP\n                                     Basic Authorization (optional)\n\n      :param bool autoclose: Automatically close websocket connection on close\n                             message from server. If *autoclose* is False\n                             then close procedure has to be handled manually.\n                             ``True`` by default\n\n      :param bool autoping: automatically send *pong* on *ping*\n                            message from server. ``True`` by default\n\n      :param float heartbeat: Send *ping* message every *heartbeat*\n                              seconds and wait *pong* response, if\n                              *pong* response is not received then\n                              close connection. The timer is reset on any data\n                              reception.(optional)\n\n      :param str origin: Origin header to send to server(optional)\n\n      :param params: Mapping, iterable of tuple of *key*/*value* pairs or\n                     string to be sent as parameters in the query\n                     string of the new request. Ignored for subsequent\n                     redirected requests (optional)\n\n                     Allowed values are:\n\n                     - :class:`collections.abc.Mapping` e.g. :class:`dict`,\n                       :class:`multidict.MultiDict` or\n                       :class:`multidict.MultiDictProxy`\n                     - :class:`collections.abc.Iterable` e.g. :class:`tuple` or\n                       :class:`list`\n                     - :class:`str` with preferably url-encoded content\n                       (**Warning:** content will not be encoded by *aiohttp*)\n\n      :param dict headers: HTTP Headers to send with\n                           the request (optional)\n\n      :param str proxy: Proxy URL, :class:`str` or :class:`~yarl.URL` (optional)\n\n      :param aiohttp.BasicAuth proxy_auth: an object that represents proxy HTTP\n                                           Basic Authorization (optional)\n\n      :param ssl: SSL validation mode. ``True`` for default SSL check\n                  (:func:`ssl.create_default_context` is used),\n                  ``False`` for skip SSL certificate validation,\n                  :class:`aiohttp.Fingerprint` for fingerprint\n                  validation, :class:`ssl.SSLContext` for custom SSL\n                  certificate validation.\n\n                  Supersedes *verify_ssl*, *ssl_context* and\n                  *fingerprint* parameters.\n\n         .. versionadded:: 3.0\n\n      :param bool verify_ssl: Perform SSL certificate validation for\n         *HTTPS* requests (enabled by default). May be disabled to\n         skip validation for sites with invalid certificates.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=False``\n\n      :param bytes fingerprint: Pass the SHA256 digest of the expected\n         certificate in DER format to verify that the certificate the\n         server presents matches. Useful for `certificate pinning\n         <https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning>`_.\n\n         Note: use of MD5 or SHA1 digests is insecure and deprecated.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=aiohttp.Fingerprint(digest)``\n\n      :param ssl.SSLContext ssl_context: ssl context used for processing\n         *HTTPS* requests (optional).\n\n         *ssl_context* may be used for configuring certification\n         authority channel, supported SSL options etc.\n\n         .. versionadded:: 2.3\n\n         .. deprecated:: 3.0\n\n            Use ``ssl=ssl_context``\n\n      :param dict proxy_headers: HTTP headers to send to the proxy if the\n         parameter proxy has been provided.\n\n         .. versionadded:: 2.3\n\n      :param int compress: Enable Per-Message Compress Extension support.\n                           0 for disable, 9 to 15 for window bit support.\n                           Default value is 0.\n\n         .. versionadded:: 2.3\n\n      :param int max_msg_size: maximum size of read websocket message,\n                               4 MB by default. To disable the size\n                               limit use ``0``.\n\n         .. versionadded:: 3.3\n\n      :param str method: HTTP method to establish WebSocket connection,\n                         ``'GET'`` by default.\n\n         .. versionadded:: 3.5\n\n\n   .. method:: close()\n      :async:\n\n      Close underlying connector.\n\n      Release all acquired resources.\n\n   .. method:: detach()\n\n      Detach connector from session without closing the former.\n\n      Session is switched to closed state anyway.\n\n\n\nBasic API\n---------\n\nWhile we encourage :class:`ClientSession` usage we also provide simple\ncoroutines for making HTTP requests.\n\nBasic API is good for performing simple HTTP requests without\nkeepaliving, cookies and complex connection stuff like properly configured SSL\ncertification chaining.\n\n\n.. function:: request(method, url, *, params=None, data=None, \\\n                        json=None,\\\n                        headers=None, cookies=None, auth=None, \\\n                        allow_redirects=True, max_redirects=10, \\\n                        encoding='utf-8', \\\n                        version=HttpVersion(major=1, minor=1), \\\n                        compress=None, chunked=None, expect100=False, raise_for_status=False, \\\n                        read_bufsize=None, \\\n                        connector=None, loop=None,\\\n                        read_until_eof=True, timeout=sentinel)\n   :async:\n\n   Asynchronous context manager for performing an asynchronous HTTP\n   request. Returns a :class:`ClientResponse` response object. Use as\n   an async context manager.\n\n   :param str method: HTTP method\n\n   :param url: Request URL, :class:`~yarl.URL` or :class:`str` that will\n               be encoded with :class:`~yarl.URL` (see :class:`~yarl.URL`\n               to skip encoding).\n\n   :param dict params: Parameters to be sent in the query\n                       string of the new request (optional)\n\n   :param data: The data to send in the body of the request. This can be a\n                :class:`FormData` object or anything that can be passed into\n                :class:`FormData`, e.g. a dictionary, bytes, or file-like object.\n                (optional)\n\n   :param json: Any json compatible python object (optional). *json* and *data*\n                parameters could not be used at the same time.\n\n   :param dict headers: HTTP Headers to send with the request (optional)\n\n   :param dict cookies: Cookies to send with the request (optional)\n\n   :param aiohttp.BasicAuth auth: an object that represents HTTP Basic\n                                  Authorization (optional)\n\n   :param bool allow_redirects: If set to ``False``, do not follow redirects.\n                                ``True`` by default (optional).\n\n   :param aiohttp.protocol.HttpVersion version: Request HTTP version (optional)\n\n   :param bool compress: Set to ``True`` if request has to be compressed\n                         with deflate encoding.\n                         ``False`` instructs aiohttp to not compress data.\n                         ``None`` by default (optional).\n\n   :param int chunked: Enables chunked transfer encoding.\n                       ``None`` by default (optional).\n\n   :param bool expect100: Expect 100-continue response from server.\n                          ``False`` by default (optional).\n\n   :param bool raise_for_status: Automatically call\n                                 :meth:`ClientResponse.raise_for_status()`\n                                 for response if set to ``True``.  If\n                                 set to ``None`` value from\n                                 ``ClientSession`` will be used.\n                                 ``None`` by default (optional).\n\n      .. versionadded:: 3.4\n\n   :param aiohttp.BaseConnector connector: BaseConnector sub-class\n      instance to support connection pooling.\n\n   :param bool read_until_eof: Read response until EOF if response\n                               does not have Content-Length header.\n                               ``True`` by default (optional).\n\n   :param int read_bufsize: Size of the read buffer (:attr:`ClientResponse.content`).\n                            ``None`` by default,\n                            it means that the session global value is used.\n\n      .. versionadded:: 3.7\n\n   :param timeout: a :class:`ClientTimeout` settings structure, 300 seconds (5min)\n        total timeout by default.\n\n   :param loop: :ref:`event loop<asyncio-event-loop>`\n                used for processing HTTP requests.\n                If param is ``None``, :func:`asyncio.get_event_loop`\n                is used for getting default event loop.\n\n      .. deprecated:: 2.0\n\n   :return ClientResponse: a :class:`client response <ClientResponse>` object.\n\n   Usage::\n\n      import aiohttp\n\n      async def fetch():\n          async with aiohttp.request('GET',\n                  'http://python.org/') as resp:\n              assert resp.status == 200\n              print(await resp.text())\n\n\n.. _aiohttp-client-reference-connectors:\n\nConnectors\n----------\n\nConnectors are transports for aiohttp client API.\n\nThere are standard connectors:\n\n1. :class:`TCPConnector` for regular *TCP sockets* (both *HTTP* and\n   *HTTPS* schemes supported).\n2. :class:`UnixConnector` for connecting via UNIX socket (it's used mostly for\n   testing purposes).\n\nAll connector classes should be derived from :class:`BaseConnector`.\n\nBy default all *connectors* support *keep-alive connections* (behavior\nis controlled by *force_close* constructor's parameter).\n\n\n.. class:: BaseConnector(*, keepalive_timeout=15, \\\n                         force_close=False, limit=100, limit_per_host=0, \\\n                         enable_cleanup_closed=False, loop=None)\n\n   Base class for all connectors.\n\n   :param float keepalive_timeout: timeout for connection reusing\n                                   after releasing (optional). Values\n                                   ``0``. For disabling *keep-alive*\n                                   feature use ``force_close=True``\n                                   flag.\n\n   :param int limit: total number simultaneous connections. If *limit* is\n                     ``0`` the connector has no limit (default: 100).\n\n   :param int limit_per_host: limit simultaneous connections to the same\n      endpoint.  Endpoints are the same if they are\n      have equal ``(host, port, is_ssl)`` triple.\n      If *limit* is ``0`` the connector has no limit (default: 0).\n\n   :param bool force_close: close underlying sockets after\n                            connection releasing (optional).\n\n   :param bool enable_cleanup_closed: some SSL servers do not properly complete\n      SSL shutdown process, in that case asyncio leaks ssl connections.\n      If this parameter is set to True, aiohttp additionally aborts underlining\n      transport after 2 seconds. It is off by default.\n\n\n   :param loop: :ref:`event loop<asyncio-event-loop>`\n      used for handling connections.\n      If param is ``None``, :func:`asyncio.get_event_loop`\n      is used for getting default event loop.\n\n      .. deprecated:: 2.0\n\n   .. attribute:: closed\n\n      Read-only property, ``True`` if connector is closed.\n\n   .. attribute:: force_close\n\n      Read-only property, ``True`` if connector should ultimately\n      close connections on releasing.\n\n   .. attribute:: limit\n\n      The total number for simultaneous connections.\n      If limit is 0 the connector has no limit. The default limit size is 100.\n\n   .. attribute:: limit_per_host\n\n      The limit for simultaneous connections to the same\n      endpoint.\n\n      Endpoints are the same if they are have equal ``(host, port,\n      is_ssl)`` triple.\n\n      If *limit_per_host* is ``0`` the connector has no limit per host.\n\n      Read-only property.\n\n   .. method:: close()\n      :async:\n\n      Close all opened connections.\n\n   .. method:: connect(request)\n      :async:\n\n      Get a free connection from pool or create new one if connection\n      is absent in the pool.\n\n      The call may be paused if :attr:`limit` is exhausted until used\n      connections returns to pool.\n\n      :param aiohttp.ClientRequest request: request object\n                                                   which is connection\n                                                   initiator.\n\n      :return: :class:`Connection` object.\n\n   .. method:: _create_connection(req)\n      :async:\n\n      Abstract method for actual connection establishing, should be\n      overridden in subclasses.\n\n\n.. class:: TCPConnector(*, ssl=True, verify_ssl=True, fingerprint=None, \\\n                 use_dns_cache=True, ttl_dns_cache=10, \\\n                 family=0, ssl_context=None, local_addr=None, \\\n                 resolver=None, keepalive_timeout=sentinel, \\\n                 force_close=False, limit=100, limit_per_host=0, \\\n                 enable_cleanup_closed=False, timeout_ceil_threshold=5, \\\n                 happy_eyeballs_delay=0.25, interleave=None, loop=None)\n\n   Connector for working with *HTTP* and *HTTPS* via *TCP* sockets.\n\n   The most common transport. When you don't know what connector type\n   to use, use a :class:`TCPConnector` instance.\n\n   :class:`TCPConnector` inherits from :class:`BaseConnector`.\n\n   Constructor accepts all parameters suitable for\n   :class:`BaseConnector` plus several TCP-specific ones:\n\n      :param ssl: SSL validation mode. ``True`` for default SSL check\n                  (:func:`ssl.create_default_context` is used),\n                  ``False`` for skip SSL certificate validation,\n                  :class:`aiohttp.Fingerprint` for fingerprint\n                  validation, :class:`ssl.SSLContext` for custom SSL\n                  certificate validation.\n\n                  Supersedes *verify_ssl*, *ssl_context* and\n                  *fingerprint* parameters.\n\n         .. versionadded:: 3.0\n\n   :param bool verify_ssl: perform SSL certificate validation for\n      *HTTPS* requests (enabled by default). May be disabled to\n      skip validation for sites with invalid certificates.\n\n      .. deprecated:: 2.3\n\n         Pass *verify_ssl* to ``ClientSession.get()`` etc.\n\n   :param bytes fingerprint: pass the SHA256 digest of the expected\n      certificate in DER format to verify that the certificate the\n      server presents matches. Useful for `certificate pinning\n      <https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning>`_.\n\n      Note: use of MD5 or SHA1 digests is insecure and deprecated.\n\n      .. deprecated:: 2.3\n\n         Pass *verify_ssl* to ``ClientSession.get()`` etc.\n\n   :param bool use_dns_cache: use internal cache for DNS lookups, ``True``\n      by default.\n\n      Enabling an option *may* speedup connection\n      establishing a bit but may introduce some\n      *side effects* also.\n\n   :param int ttl_dns_cache: expire after some seconds the DNS entries, ``None``\n      means cached forever. By default 10 seconds (optional).\n\n      In some environments the IP addresses related to a specific HOST can\n      change after a specific time. Use this option to keep the DNS cache\n      updated refreshing each entry after N seconds.\n\n   :param int limit: total number simultaneous connections. If *limit* is\n                     ``0`` the connector has no limit (default: 100).\n\n   :param int limit_per_host: limit simultaneous connections to the same\n      endpoint.  Endpoints are the same if they are\n      have equal ``(host, port, is_ssl)`` triple.\n      If *limit* is ``0`` the connector has no limit (default: 0).\n\n   :param aiohttp.abc.AbstractResolver resolver: custom resolver\n      instance to use.  ``aiohttp.DefaultResolver`` by\n      default (asynchronous if ``aiodns>=1.1`` is installed).\n\n      Custom resolvers allow to resolve hostnames differently than the\n      way the host is configured.\n\n      The resolver is ``aiohttp.ThreadedResolver`` by default,\n      asynchronous version is pretty robust but might fail in\n      very rare cases.\n\n   :param int family: TCP socket family, both IPv4 and IPv6 by default.\n                      For *IPv4* only use :data:`socket.AF_INET`,\n                      for  *IPv6* only -- :data:`socket.AF_INET6`.\n\n                      *family* is ``0`` by default, that means both\n                      IPv4 and IPv6 are accepted. To specify only\n                      concrete version please pass\n                      :data:`socket.AF_INET` or\n                      :data:`socket.AF_INET6` explicitly.\n\n   :param ssl.SSLContext ssl_context: SSL context used for processing\n      *HTTPS* requests (optional).\n\n      *ssl_context* may be used for configuring certification\n      authority channel, supported SSL options etc.\n\n   :param tuple local_addr: tuple of ``(local_host, local_port)`` used to bind\n      socket locally if specified.\n\n   :param bool force_close: close underlying sockets after\n                            connection releasing (optional).\n\n   :param bool enable_cleanup_closed: Some ssl servers do not properly complete\n      SSL shutdown process, in that case asyncio leaks SSL connections.\n      If this parameter is set to True, aiohttp additionally aborts underlining\n      transport after 2 seconds. It is off by default.\n\n   :param float happy_eyeballs_delay: The amount of time in seconds to wait for a\n      connection attempt to complete, before starting the next attempt in parallel.\n      This is the “Connection Attempt Delay” as defined in RFC 8305. To disable\n      Happy Eyeballs, set this to ``None``. The default value recommended by the\n      RFC is 0.25 (250 milliseconds).\n\n        .. versionadded:: 3.10\n\n   :param int interleave: controls address reordering when a host name resolves\n      to multiple IP addresses. If ``0`` or unspecified, no reordering is done, and\n      addresses are tried in the order returned by the resolver. If a positive\n      integer is specified, the addresses are interleaved by address family, and\n      the given integer is interpreted as “First Address Family Count” as defined\n      in RFC 8305. The default is ``0`` if happy_eyeballs_delay is not specified, and\n      ``1`` if it is.\n\n        .. versionadded:: 3.10\n\n   .. attribute:: family\n\n      *TCP* socket family e.g. :data:`socket.AF_INET` or\n      :data:`socket.AF_INET6`\n\n      Read-only property.\n\n   .. attribute:: dns_cache\n\n      Use quick lookup in internal *DNS* cache for host names if ``True``.\n\n      Read-only :class:`bool` property.\n\n   .. attribute:: cached_hosts\n\n      The cache of resolved hosts if :attr:`dns_cache` is enabled.\n\n      Read-only :class:`types.MappingProxyType` property.\n\n   .. method:: clear_dns_cache(self, host=None, port=None)\n\n      Clear internal *DNS* cache.\n\n      Remove specific entry if both *host* and *port* are specified,\n      clear all cache otherwise.\n\n\n.. class:: UnixConnector(path, *, conn_timeout=None, \\\n                         keepalive_timeout=30, limit=100, \\\n                         force_close=False, loop=None)\n\n   Unix socket connector.\n\n   Use :class:`UnixConnector` for sending *HTTP/HTTPS* requests\n   through *UNIX Sockets* as underlying transport.\n\n   UNIX sockets are handy for writing tests and making very fast\n   connections between processes on the same host.\n\n   :class:`UnixConnector` is inherited from :class:`BaseConnector`.\n\n    Usage::\n\n       conn = UnixConnector(path='/path/to/socket')\n       session = ClientSession(connector=conn)\n       async with session.get('http://python.org') as resp:\n           ...\n\n   Constructor accepts all parameters suitable for\n   :class:`BaseConnector` plus UNIX-specific one:\n\n   :param str path: Unix socket path\n\n\n   .. attribute:: path\n\n      Path to *UNIX socket*, read-only :class:`str` property.\n\n\n.. class:: Connection\n\n   Encapsulates single connection in connector object.\n\n   End user should never create :class:`Connection` instances manually\n   but get it by :meth:`BaseConnector.connect` coroutine.\n\n   .. attribute:: closed\n\n      :class:`bool` read-only property, ``True`` if connection was\n      closed, released or detached.\n\n   .. attribute:: loop\n\n      Event loop used for connection\n\n      .. deprecated:: 3.5\n\n   .. attribute:: transport\n\n      Connection transport\n\n   .. method:: close()\n\n      Close connection with forcibly closing underlying socket.\n\n   .. method:: release()\n\n      Release connection back to connector.\n\n      Underlying socket is not closed, the connection may be reused\n      later if timeout (30 seconds by default) for connection was not\n      expired.\n\n\nResponse object\n---------------\n\n.. class:: ClientResponse\n\n   Client response returned by :meth:`aiohttp.ClientSession.request` and family.\n\n   User never creates the instance of ClientResponse class but gets it\n   from API calls.\n\n   :class:`ClientResponse` supports async context manager protocol, e.g.::\n\n       resp = await client_session.get(url)\n       async with resp:\n           assert resp.status == 200\n\n   After exiting from ``async with`` block response object will be\n   *released* (see :meth:`release` method).\n\n   .. attribute:: version\n\n      Response's version, :class:`~aiohttp.protocol.HttpVersion` instance.\n\n   .. attribute:: status\n\n      HTTP status code of response (:class:`int`), e.g. ``200``.\n\n   .. attribute:: reason\n\n      HTTP status reason of response (:class:`str`), e.g. ``\"OK\"``.\n\n   .. attribute:: ok\n\n      Boolean representation of HTTP status code (:class:`bool`).\n      ``True`` if ``status`` is less than ``400``; otherwise, ``False``.\n\n   .. attribute:: method\n\n      Request's method (:class:`str`).\n\n   .. attribute:: url\n\n      URL of request (:class:`~yarl.URL`).\n\n   .. attribute:: real_url\n\n      Unmodified URL of request with URL fragment unstripped (:class:`~yarl.URL`).\n\n      .. versionadded:: 3.2\n\n   .. attribute:: connection\n\n      :class:`Connection` used for handling response.\n\n   .. attribute:: content\n\n      Payload stream, which contains response's BODY (:class:`StreamReader`).\n      It supports various reading methods depending on the expected format.\n      When chunked transfer encoding is used by the server, allows retrieving\n      the actual http chunks.\n\n      Reading from the stream may raise\n      :exc:`aiohttp.ClientPayloadError` if the response object is\n      closed before response receives all data or in case if any\n      transfer encoding related errors like malformed chunked\n      encoding of broken compression data.\n\n   .. attribute:: cookies\n\n      HTTP cookies of response (*Set-Cookie* HTTP header,\n      :class:`~http.cookies.SimpleCookie`).\n\n   .. attribute:: headers\n\n      A case-insensitive multidict proxy with HTTP headers of\n      response, :class:`~multidict.CIMultiDictProxy`.\n\n   .. attribute:: raw_headers\n\n      Unmodified HTTP headers of response as unconverted bytes, a sequence of\n      ``(key, value)`` pairs.\n\n   .. attribute:: links\n\n      Link HTTP header parsed into a :class:`~multidict.MultiDictProxy`.\n\n      For each link, key is link param `rel` when it exists, or link url as\n      :class:`str` otherwise, and value is :class:`~multidict.MultiDictProxy`\n      of link params and url at key `url` as :class:`~yarl.URL` instance.\n\n      .. versionadded:: 3.2\n\n   .. attribute:: content_type\n\n      Read-only property with *content* part of *Content-Type* header.\n\n      .. note::\n\n         Returns value is ``'application/octet-stream'`` if no\n         Content-Type header present in HTTP headers according to\n         :rfc:`2616`. To make sure Content-Type header is not present in\n         the server reply, use :attr:`headers` or :attr:`raw_headers`, e.g.\n         ``'CONTENT-TYPE' not in resp.headers``.\n\n   .. attribute:: charset\n\n      Read-only property that specifies the *encoding* for the request's BODY.\n\n      The value is parsed from the *Content-Type* HTTP header.\n\n      Returns :class:`str` like ``'utf-8'`` or ``None`` if no *Content-Type*\n      header present in HTTP headers or it has no charset information.\n\n   .. attribute:: content_disposition\n\n      Read-only property that specified the *Content-Disposition* HTTP header.\n\n      Instance of :class:`ContentDisposition` or ``None`` if no *Content-Disposition*\n      header present in HTTP headers.\n\n   .. attribute:: history\n\n      A :class:`~collections.abc.Sequence` of :class:`ClientResponse`\n      objects of preceding requests (earliest request first) if there were\n      redirects, an empty sequence otherwise.\n\n   .. method:: close()\n\n      Close response and underlying connection.\n\n      For :term:`keep-alive` support see :meth:`release`.\n\n   .. method:: read()\n      :async:\n\n      Read the whole response's body as :class:`bytes`.\n\n      Close underlying connection if data reading gets an error,\n      release connection otherwise.\n\n      Raise an :exc:`aiohttp.ClientResponseError` if the data can't\n      be read.\n\n      :return bytes: read *BODY*.\n\n      .. seealso:: :meth:`close`, :meth:`release`.\n\n   .. method:: release()\n\n      It is not required to call `release` on the response\n      object. When the client fully receives the payload, the\n      underlying connection automatically returns back to pool. If the\n      payload is not fully read, the connection is closed\n\n   .. method:: raise_for_status()\n\n      Raise an :exc:`aiohttp.ClientResponseError` if the response\n      status is 400 or higher.\n\n      Do nothing for success responses (less than 400).\n\n   .. method:: text(encoding=None)\n      :async:\n\n      Read response's body and return decoded :class:`str` using\n      specified *encoding* parameter.\n\n      If *encoding* is ``None`` content encoding is determined from the\n      Content-Type header, or using the ``fallback_charset_resolver`` function.\n\n      Close underlying connection if data reading gets an error,\n      release connection otherwise.\n\n      :param str encoding: text encoding used for *BODY* decoding, or\n                           ``None`` for encoding autodetection\n                           (default).\n\n\n      :raises: :exc:`UnicodeDecodeError` if decoding fails. See also\n               :meth:`get_encoding`.\n\n      :return str: decoded *BODY*\n\n   .. method:: json(*, encoding=None, loads=json.loads, \\\n                      content_type='application/json')\n      :async:\n\n      Read response's body as *JSON*, return :class:`dict` using\n      specified *encoding* and *loader*. If data is not still available\n      a ``read`` call will be done.\n\n      If response's `content-type` does not match `content_type` parameter\n      :exc:`aiohttp.ContentTypeError` get raised.\n      To disable content type check pass ``None`` value.\n\n      :param str encoding: text encoding used for *BODY* decoding, or\n                           ``None`` for encoding autodetection\n                           (default).\n\n                           By the standard JSON encoding should be\n                           ``UTF-8`` but practice beats purity: some\n                           servers return non-UTF\n                           responses. Autodetection works pretty fine\n                           anyway.\n\n      :param collections.abc.Callable loads: :term:`callable` used for loading *JSON*\n                             data, :func:`json.loads` by default.\n\n      :param str content_type: specify response's content-type, if content type\n         does not match raise :exc:`aiohttp.ClientResponseError`.\n         To disable `content-type` check, pass ``None`` as value.\n         (default: `application/json`).\n\n      :return: *BODY* as *JSON* data parsed by *loads* parameter or\n               ``None`` if *BODY* is empty or contains white-spaces only.\n\n   .. attribute:: request_info\n\n       A namedtuple with request URL and headers from :class:`~aiohttp.ClientRequest`\n       object, :class:`aiohttp.RequestInfo` instance.\n\n   .. method:: get_encoding()\n\n      Retrieve content encoding using ``charset`` info in ``Content-Type`` HTTP header.\n      If no charset is present or the charset is not understood by Python, the\n      ``fallback_charset_resolver`` function associated with the ``ClientSession`` is called.\n\n      .. versionadded:: 3.0\n\n\nClientWebSocketResponse\n-----------------------\n\nTo connect to a websocket server :func:`aiohttp.ws_connect` or\n:meth:`aiohttp.ClientSession.ws_connect` coroutines should be used, do\nnot create an instance of class :class:`ClientWebSocketResponse`\nmanually.\n\n.. class:: ClientWebSocketResponse()\n\n   Class for handling client-side websockets.\n\n   .. attribute:: closed\n\n      Read-only property, ``True`` if :meth:`close` has been called or\n      :const:`~aiohttp.WSMsgType.CLOSE` message has been received from peer.\n\n   .. attribute:: protocol\n\n      Websocket *subprotocol* chosen after :meth:`start` call.\n\n      May be ``None`` if server and client protocols are\n      not overlapping.\n\n   .. method:: get_extra_info(name, default=None)\n\n      Reads optional extra information from the connection's transport.\n      If no value associated with ``name`` is found, ``default`` is returned.\n\n      See :meth:`asyncio.BaseTransport.get_extra_info`\n\n      :param str name: The key to look up in the transport extra information.\n\n      :param default: Default value to be used when no value for ``name`` is\n                      found (default is ``None``).\n\n   .. method:: exception()\n\n      Returns exception if any occurs or returns None.\n\n   .. method:: ping(message=b'')\n      :async:\n\n      Send :const:`~aiohttp.WSMsgType.PING` to peer.\n\n      :param message: optional payload of *ping* message,\n                      :class:`str` (converted to *UTF-8* encoded bytes)\n                      or :class:`bytes`.\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`\n\n   .. method:: pong(message=b'')\n      :async:\n\n      Send :const:`~aiohttp.WSMsgType.PONG` to peer.\n\n      :param message: optional payload of *pong* message,\n                      :class:`str` (converted to *UTF-8* encoded bytes)\n                      or :class:`bytes`.\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`\n\n   .. method:: send_str(data, compress=None)\n      :async:\n\n      Send *data* to peer as :const:`~aiohttp.WSMsgType.TEXT` message.\n\n      :param str data: data to send.\n\n      :param int compress: sets specific level of compression for\n                           single message,\n                           ``None`` for not overriding per-socket setting.\n\n      :raise TypeError: if data is not :class:`str`\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`,\n         *compress* parameter added.\n\n   .. method:: send_bytes(data, compress=None)\n      :async:\n\n      Send *data* to peer as :const:`~aiohttp.WSMsgType.BINARY` message.\n\n      :param data: data to send.\n\n      :param int compress: sets specific level of compression for\n                           single message,\n                           ``None`` for not overriding per-socket setting.\n\n      :raise TypeError: if data is not :class:`bytes`,\n                        :class:`bytearray` or :class:`memoryview`.\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`,\n         *compress* parameter added.\n\n   .. method:: send_json(data, compress=None, *, dumps=json.dumps)\n      :async:\n\n      Send *data* to peer as JSON string.\n\n      :param data: data to send.\n\n      :param int compress: sets specific level of compression for\n                           single message,\n                           ``None`` for not overriding per-socket setting.\n\n      :param collections.abc.Callable dumps: any :term:`callable` that accepts an object and\n                             returns a JSON string\n                             (:func:`json.dumps` by default).\n\n      :raise RuntimeError: if connection is not started or closing\n\n      :raise ValueError: if data is not serializable object\n\n      :raise TypeError: if value returned by ``dumps(data)`` is not\n                        :class:`str`\n\n      .. versionchanged:: 3.0\n\n         The method is converted into :term:`coroutine`,\n         *compress* parameter added.\n\n   .. method:: close(*, code=WSCloseCode.OK, message=b'')\n      :async:\n\n      A :ref:`coroutine<coroutine>` that initiates closing handshake by sending\n      :const:`~aiohttp.WSMsgType.CLOSE` message. It waits for\n      close response from server. To add a timeout to `close()` call\n      just wrap the call with `asyncio.wait()` or `asyncio.wait_for()`.\n\n      :param int code: closing code. See also :class:`~aiohttp.WSCloseCode`.\n\n      :param message: optional payload of *close* message,\n         :class:`str` (converted to *UTF-8* encoded bytes) or :class:`bytes`.\n\n   .. method:: receive()\n      :async:\n\n      A :ref:`coroutine<coroutine>` that waits upcoming *data*\n      message from peer and returns it.\n\n      The coroutine implicitly handles\n      :const:`~aiohttp.WSMsgType.PING`,\n      :const:`~aiohttp.WSMsgType.PONG` and\n      :const:`~aiohttp.WSMsgType.CLOSE` without returning the\n      message.\n\n      It process *ping-pong game* and performs *closing handshake* internally.\n\n      :return: :class:`~aiohttp.WSMessage`\n\n   .. method:: receive_str()\n      :async:\n\n      A :ref:`coroutine<coroutine>` that calls :meth:`receive` but\n      also asserts the message type is\n      :const:`~aiohttp.WSMsgType.TEXT`.\n\n      :return str: peer's message content.\n\n      :raise TypeError: if message is :const:`~aiohttp.WSMsgType.BINARY`.\n\n   .. method:: receive_bytes()\n      :async:\n\n      A :ref:`coroutine<coroutine>` that calls :meth:`receive` but\n      also asserts the message type is\n      :const:`~aiohttp.WSMsgType.BINARY`.\n\n      :return bytes: peer's message content.\n\n      :raise TypeError: if message is :const:`~aiohttp.WSMsgType.TEXT`.\n\n   .. method:: receive_json(*, loads=json.loads)\n      :async:\n\n      A :ref:`coroutine<coroutine>` that calls :meth:`receive_str` and loads\n      the JSON string to a Python dict.\n\n      :param collections.abc.Callable loads: any :term:`callable` that accepts\n                              :class:`str` and returns :class:`dict`\n                              with parsed JSON (:func:`json.loads` by\n                              default).\n\n      :return dict: loaded JSON content\n\n      :raise TypeError: if message is :const:`~aiohttp.WSMsgType.BINARY`.\n      :raise ValueError: if message is not valid JSON.\n\n\nUtilities\n---------\n\n\n.. class:: ClientTimeout(*, total=None, connect=None, \\\n                         sock_connect=None, sock_read=None)\n\n   A data class for client timeout settings.\n\n   See :ref:`aiohttp-client-timeouts` for usage examples.\n\n   .. attribute:: total\n\n      Total number of seconds for the whole request.\n\n      :class:`float`, ``None`` by default.\n\n   .. attribute:: connect\n\n      Maximal number of seconds for acquiring a connection from pool.  The time\n      consists connection establishment for a new connection or\n      waiting for a free connection from a pool if pool connection\n      limits are exceeded.\n\n      For pure socket connection establishment time use\n      :attr:`sock_connect`.\n\n      :class:`float`, ``None`` by default.\n\n   .. attribute:: sock_connect\n\n      Maximal number of seconds for connecting to a peer for a new connection, not\n      given from a pool.  See also :attr:`connect`.\n\n      :class:`float`, ``None`` by default.\n\n   .. attribute:: sock_read\n\n      Maximal number of seconds for reading a portion of data from a peer.\n\n      :class:`float`, ``None`` by default.\n\n   .. versionadded:: 3.3\n\n\n   .. note::\n\n      Timeouts of 5 seconds or more are rounded for scheduling on the next\n      second boundary (an absolute time where microseconds part is zero) for the\n      sake of performance.\n\n      E.g., assume a timeout is ``10``, absolute time when timeout should expire\n      is ``loop.time() + 5``, and it points to ``12345.67 + 10`` which is equal\n      to ``12355.67``.\n\n      The absolute time for the timeout cancellation is ``12356``.\n\n      It leads to grouping all close scheduled timeout expirations to exactly\n      the same time to reduce amount of loop wakeups.\n\n      .. versionchanged:: 3.7\n\n         Rounding to the next seconds boundary is disabled for timeouts smaller\n         than 5 seconds for the sake of easy debugging.\n\n         In turn, tiny timeouts can lead to significant performance degradation\n         on production environment.\n\n\n.. class:: ETag(name, is_weak=False)\n\n   Represents `ETag` identifier.\n\n   .. attribute:: value\n\n      Value of corresponding etag without quotes.\n\n   .. attribute:: is_weak\n\n      Flag indicates that etag is weak (has `W/` prefix).\n\n   .. versionadded:: 3.8\n\n\n.. class:: RequestInfo()\n\n   A data class with request URL and headers from :class:`~aiohttp.ClientRequest`\n   object, available as :attr:`ClientResponse.request_info` attribute.\n\n   .. attribute:: url\n\n      Requested *url*, :class:`yarl.URL` instance.\n\n   .. attribute:: method\n\n      Request HTTP method like ``'GET'`` or ``'POST'``, :class:`str`.\n\n   .. attribute:: headers\n\n      HTTP headers for request, :class:`multidict.CIMultiDict` instance.\n\n   .. attribute:: real_url\n\n      Requested *url* with URL fragment unstripped, :class:`yarl.URL` instance.\n\n      .. versionadded:: 3.2\n\n\n.. class:: BasicAuth(login, password='', encoding='latin1')\n\n   HTTP basic authentication helper.\n\n   :param str login: login\n   :param str password: password\n   :param str encoding: encoding (``'latin1'`` by default)\n\n\n   Should be used for specifying authorization data in client API,\n   e.g. *auth* parameter for :meth:`ClientSession.request() <aiohttp.ClientSession.request>`.\n\n\n   .. classmethod:: decode(auth_header, encoding='latin1')\n\n      Decode HTTP basic authentication credentials.\n\n      :param str auth_header:  The ``Authorization`` header to decode.\n      :param str encoding: (optional) encoding ('latin1' by default)\n\n      :return:  decoded authentication data, :class:`BasicAuth`.\n\n   .. classmethod:: from_url(url)\n\n      Constructed credentials info from url's *user* and *password*\n      parts.\n\n      :return: credentials data, :class:`BasicAuth` or ``None`` is\n                credentials are not provided.\n\n      .. versionadded:: 2.3\n\n   .. method:: encode()\n\n      Encode credentials into string suitable for ``Authorization``\n      header etc.\n\n      :return: encoded authentication data, :class:`str`.\n\n\n.. class:: CookieJar(*, unsafe=False, quote_cookie=True, treat_as_secure_origin = [])\n\n   The cookie jar instance is available as :attr:`ClientSession.cookie_jar`.\n\n   The jar contains :class:`~http.cookies.Morsel` items for storing\n   internal cookie data.\n\n   API provides a count of saved cookies::\n\n       len(session.cookie_jar)\n\n   These cookies may be iterated over::\n\n       for cookie in session.cookie_jar:\n           print(cookie.key)\n           print(cookie[\"domain\"])\n\n   The class implements :class:`collections.abc.Iterable`,\n   :class:`collections.abc.Sized` and\n   :class:`aiohttp.abc.AbstractCookieJar` interfaces.\n\n   Implements cookie storage adhering to RFC 6265.\n\n   :param bool unsafe: (optional) Whether to accept cookies from IPs.\n\n   :param bool quote_cookie: (optional) Whether to quote cookies according to\n                             :rfc:`2109`.  Some backend systems\n                             (not compatible with RFC mentioned above)\n                             does not support quoted cookies.\n\n      .. versionadded:: 3.7\n\n   :param treat_as_secure_origin: (optional) Mark origins as secure\n                                  for cookies marked as Secured. Possible types are\n\n                                  Possible types are:\n\n                                  - :class:`tuple` or :class:`list` of\n                                    :class:`str` or :class:`yarl.URL`\n                                  - :class:`str`\n                                  - :class:`yarl.URL`\n\n      .. versionadded:: 3.8\n\n   .. method:: update_cookies(cookies, response_url=None)\n\n      Update cookies returned by server in ``Set-Cookie`` header.\n\n      :param cookies: a :class:`collections.abc.Mapping`\n         (e.g. :class:`dict`, :class:`~http.cookies.SimpleCookie`) or\n         *iterable* of *pairs* with cookies returned by server's\n         response.\n\n      :param ~yarl.URL response_url: URL of response, ``None`` for *shared\n         cookies*.  Regular cookies are coupled with server's URL and\n         are sent only to this server, shared ones are sent in every\n         client request.\n\n   .. method:: filter_cookies(request_url)\n\n      Return jar's cookies acceptable for URL and available in\n      ``Cookie`` header for sending client requests for given URL.\n\n      :param ~yarl.URL response_url: request's URL for which cookies are asked.\n\n      :return: :class:`http.cookies.SimpleCookie` with filtered\n         cookies for given URL.\n\n   .. method:: save(file_path)\n\n      Write a pickled representation of cookies into the file\n      at provided path.\n\n      :param file_path: Path to file where cookies will be serialized,\n          :class:`str` or :class:`pathlib.Path` instance.\n\n   .. method:: load(file_path)\n\n      Load a pickled representation of cookies from the file\n      at provided path.\n\n      :param file_path: Path to file from where cookies will be\n           imported, :class:`str` or :class:`pathlib.Path` instance.\n\n   .. method:: clear(predicate=None)\n\n      Removes all cookies from the jar if the predicate is ``None``. Otherwise remove only those :class:`~http.cookies.Morsel` that ``predicate(morsel)`` returns ``True``.\n\n      :param predicate: callable that gets :class:`~http.cookies.Morsel` as a parameter and returns ``True`` if this :class:`~http.cookies.Morsel` must be deleted from the jar.\n\n          .. versionadded:: 4.0\n\n   .. method:: clear_domain(domain)\n\n      Remove all cookies from the jar that belongs to the specified domain or its subdomains.\n\n      :param str domain: domain for which cookies must be deleted from the jar.\n\n      .. versionadded:: 4.0\n\n\n.. class:: DummyCookieJar(*, loop=None)\n\n   Dummy cookie jar which does not store cookies but ignores them.\n\n   Could be useful e.g. for web crawlers to iterate over Internet\n   without blowing up with saved cookies information.\n\n   To install dummy cookie jar pass it into session instance::\n\n      jar = aiohttp.DummyCookieJar()\n      session = aiohttp.ClientSession(cookie_jar=DummyCookieJar())\n\n\n.. class:: Fingerprint(digest)\n\n   Fingerprint helper for checking SSL certificates by *SHA256* digest.\n\n   :param bytes digest: *SHA256* digest for certificate in DER-encoded\n                        binary form (see\n                        :meth:`ssl.SSLSocket.getpeercert`).\n\n   To check fingerprint pass the object into :meth:`ClientSession.get`\n   call, e.g.::\n\n      import hashlib\n\n      with open(path_to_cert, 'rb') as f:\n          digest = hashlib.sha256(f.read()).digest()\n\n      await session.get(url, ssl=aiohttp.Fingerprint(digest))\n\n   .. versionadded:: 3.0\n\nFormData\n^^^^^^^^\n\nA :class:`FormData` object contains the form data and also handles\nencoding it into a body that is either ``multipart/form-data`` or\n``application/x-www-form-urlencoded``. ``multipart/form-data`` is\nused if at least one field is an :class:`io.IOBase` object or was\nadded with at least one optional argument to :meth:`add_field<aiohttp.FormData.add_field>`\n(``content_type``, ``filename``, or ``content_transfer_encoding``).\nOtherwise, ``application/x-www-form-urlencoded`` is used.\n\n:class:`FormData` instances are callable and return a :class:`aiohttp.payload.Payload`\non being called.\n\n.. class:: FormData(fields, quote_fields=True, charset=None)\n\n   Helper class for multipart/form-data and application/x-www-form-urlencoded body generation.\n\n   :param fields: A container for the key/value pairs of this form.\n\n                  Possible types are:\n\n                  - :class:`dict`\n                  - :class:`tuple` or :class:`list`\n                  - :class:`io.IOBase`, e.g. a file-like object\n                  - :class:`multidict.MultiDict` or :class:`multidict.MultiDictProxy`\n\n                  If it is a :class:`tuple` or :class:`list`, it must be a valid argument\n                  for :meth:`add_fields<aiohttp.FormData.add_fields>`.\n\n                  For :class:`dict`, :class:`multidict.MultiDict`, and :class:`multidict.MultiDictProxy`,\n                  the keys and values must be valid `name` and `value` arguments to\n                  :meth:`add_field<aiohttp.FormData.add_field>`, respectively.\n\n   .. method:: add_field(name, value, content_type=None, filename=None,\\\n                         content_transfer_encoding=None)\n\n      Add a field to the form.\n\n      :param str name: Name of the field\n\n      :param value: Value of the field\n\n                    Possible types are:\n\n                    - :class:`str`\n                    - :class:`bytes`, :class:`bytearray`, or :class:`memoryview`\n                    - :class:`io.IOBase`, e.g. a file-like object\n\n      :param str content_type: The field's content-type header (optional)\n\n      :param str filename: The field's filename (optional)\n\n                           If this is not set and ``value`` is a :class:`bytes`, :class:`bytearray`,\n                           or :class:`memoryview` object, the `name` argument is used as the filename\n                           unless ``content_transfer_encoding`` is specified.\n\n                           If ``filename`` is not set and ``value`` is an :class:`io.IOBase`\n                           object, the filename is extracted from the object if possible.\n\n      :param str content_transfer_encoding: The field's content-transfer-encoding\n                                            header (optional)\n\n   .. method:: add_fields(fields)\n\n      Add one or more fields to the form.\n\n      :param fields: An iterable containing:\n\n                     - :class:`io.IOBase`, e.g. a file-like object\n                     - :class:`multidict.MultiDict` or :class:`multidict.MultiDictProxy`\n                     - :class:`tuple` or :class:`list` of length two, containing a name-value pair\n\nClient exceptions\n-----------------\n\nException hierarchy has been significantly modified in version\n2.0. aiohttp defines only exceptions that covers connection handling\nand server response misbehaviors.  For developer specific mistakes,\naiohttp uses python standard exceptions like :exc:`ValueError` or\n:exc:`TypeError`.\n\nReading a response content may raise a :exc:`ClientPayloadError`\nexception. This exception indicates errors specific to the payload\nencoding. Such as invalid compressed data, malformed chunked-encoded\nchunks or not enough data that satisfy the content-length header.\n\nAll exceptions are available as members of *aiohttp* module.\n\n.. exception:: ClientError\n\n   Base class for all client specific exceptions.\n\n   Derived from :exc:`Exception`\n\n\n.. class:: ClientPayloadError\n\n   This exception can only be raised while reading the response\n   payload if one of these errors occurs:\n\n   1. invalid compression\n   2. malformed chunked encoding\n   3. not enough data that satisfy ``Content-Length`` HTTP header.\n\n   Derived from :exc:`ClientError`\n\n.. exception:: InvalidURL\n\n   URL used for fetching is malformed, e.g. it does not contain host\n   part.\n\n   Derived from :exc:`ClientError` and :exc:`ValueError`\n\n   .. attribute:: url\n\n      Invalid URL, :class:`yarl.URL` instance.\n\n    .. attribute:: description\n\n      Invalid URL description, :class:`str` instance or :data:`None`.\n\n.. exception:: InvalidUrlClientError\n\n   Base class for all errors related to client url.\n\n   Derived from :exc:`InvalidURL`\n\n.. exception:: RedirectClientError\n\n   Base class for all errors related to client redirects.\n\n   Derived from :exc:`ClientError`\n\n.. exception:: NonHttpUrlClientError\n\n   Base class for all errors related to non http client urls.\n\n   Derived from :exc:`ClientError`\n\n.. exception:: InvalidUrlRedirectClientError\n\n   Redirect URL is malformed, e.g. it does not contain host part.\n\n   Derived from :exc:`InvalidUrlClientError` and :exc:`RedirectClientError`\n\n.. exception:: NonHttpUrlRedirectClientError\n\n   Redirect URL does not contain http schema.\n\n   Derived from :exc:`RedirectClientError` and :exc:`NonHttpUrlClientError`\n\n\n.. class:: ContentDisposition\n\n    Represent Content-Disposition header\n\n    .. attribute:: type\n\n    A :class:`str` instance. Value of Content-Disposition header\n    itself, e.g. ``attachment``.\n\n    .. attribute:: filename\n\n    A :class:`str` instance. Content filename extracted from\n    parameters. May be ``None``.\n\n    .. attribute:: parameters\n\n    Read-only mapping contains all parameters.\n\nResponse errors\n^^^^^^^^^^^^^^^\n\n.. exception:: ClientResponseError\n\n   These exceptions could happen after we get response from server.\n\n   Derived from :exc:`ClientError`\n\n   .. attribute:: request_info\n\n      Instance of :class:`RequestInfo` object, contains information\n      about request.\n\n   .. attribute:: status\n\n      HTTP status code of response (:class:`int`), e.g. ``400``.\n\n   .. attribute:: message\n\n      Message of response (:class:`str`), e.g. ``\"OK\"``.\n\n   .. attribute:: headers\n\n      Headers in response, a list of pairs.\n\n   .. attribute:: history\n\n      History from failed response, if available, else empty tuple.\n\n      A :class:`tuple` of :class:`ClientResponse` objects used for\n      handle redirection responses.\n\n   .. attribute:: code\n\n      HTTP status code of response (:class:`int`), e.g. ``400``.\n\n      .. deprecated:: 3.1\n\n\n.. class:: ContentTypeError\n\n   Invalid content type.\n\n   Derived from :exc:`ClientResponseError`\n\n   .. versionadded:: 2.3\n\n\n.. class:: TooManyRedirects\n\n   Client was redirected too many times.\n\n   Maximum number of redirects can be configured by using\n   parameter ``max_redirects`` in :meth:`request<aiohttp.ClientSession.request>`.\n\n   Derived from :exc:`ClientResponseError`\n\n   .. versionadded:: 3.2\n\n\n.. class:: WSServerHandshakeError\n\n   Web socket server response error.\n\n   Derived from :exc:`ClientResponseError`\n\nConnection errors\n^^^^^^^^^^^^^^^^^\n\n.. class:: ClientConnectionError\n\n   These exceptions related to low-level connection problems.\n\n   Derived from :exc:`ClientError`\n\n.. class:: ClientOSError\n\n   Subset of connection errors that are initiated by an :exc:`OSError`\n   exception.\n\n   Derived from :exc:`ClientConnectionError` and :exc:`OSError`\n\n.. class:: ClientConnectorError\n\n   Connector related exceptions.\n\n   Derived from :exc:`ClientOSError`\n\n.. class:: ClientProxyConnectionError\n\n   Derived from :exc:`ClientConnectorError`\n\n.. class:: ClientSSLError\n\n   Derived from :exc:`ClientConnectorError`\n\n.. class:: ClientConnectorSSLError\n\n   Response ssl error.\n\n   Derived from :exc:`ClientSSLError` and :exc:`ssl.SSLError`\n\n.. class:: ClientConnectorCertificateError\n\n   Response certificate error.\n\n   Derived from :exc:`ClientSSLError` and :exc:`ssl.CertificateError`\n\n.. class:: UnixClientConnectorError\n\n   Derived from :exc:`ClientConnectorError`\n\n.. class:: ServerConnectionError\n\n   Derived from :exc:`ClientConnectionError`\n\n.. class:: ServerDisconnectedError\n\n   Server disconnected.\n\n   Derived from :exc:`~aiohttp.ServerConnectionError`\n\n   .. attribute:: message\n\n      Partially parsed HTTP message (optional).\n\n\n.. class:: ServerFingerprintMismatch\n\n   Server fingerprint mismatch.\n\n   Derived from :exc:`ServerConnectionError`\n\n.. class:: ServerTimeoutError\n\n   Server operation timeout: read timeout, etc.\n\n   Derived from :exc:`ServerConnectionError` and :exc:`asyncio.TimeoutError`\n\n.. class:: ConnectionTimeoutError\n\n   Connection timeout on request: e.g. read timeout.\n\n   Derived from :exc:`ServerTimeoutError`\n\n.. class:: SocketTimeoutError\n\n   Reading from socket timeout.\n\n   Derived from :exc:`ServerTimeoutError`\n\nHierarchy of exceptions\n^^^^^^^^^^^^^^^^^^^^^^^\n\n* :exc:`ClientError`\n\n  * :exc:`ClientConnectionError`\n\n    * :exc:`ClientOSError`\n\n      * :exc:`ClientConnectorError`\n\n        * :exc:`ClientProxyConnectionError`\n\n        * :exc:`ClientSSLError`\n\n          * :exc:`ClientConnectorCertificateError`\n\n          * :exc:`ClientConnectorSSLError`\n\n        * :exc:`UnixClientConnectorError`\n\n    * :exc:`ServerConnectionError`\n\n      * :exc:`ServerDisconnectedError`\n\n      * :exc:`ServerFingerprintMismatch`\n\n      * :exc:`ServerTimeoutError`\n\n        * :exc:`ConnectionTimeoutError`\n\n        * :exc:`SocketTimeoutError`\n\n  * :exc:`ClientPayloadError`\n\n  * :exc:`ClientResponseError`\n\n    * :exc:`~aiohttp.ClientHttpProxyError`\n\n    * :exc:`ContentTypeError`\n\n    * :exc:`TooManyRedirects`\n\n    * :exc:`WSServerHandshakeError`\n\n  * :exc:`InvalidURL`\n\n    * :exc:`InvalidUrlClientError`\n\n      * :exc:`InvalidUrlRedirectClientError`\n\n  * :exc:`NonHttpUrlClientError`\n\n    * :exc:`NonHttpUrlRedirectClientError`\n\n  * :exc:`RedirectClientError`\n\n    * :exc:`InvalidUrlRedirectClientError`\n\n    * :exc:`NonHttpUrlRedirectClientError`\n",
            "header": {
                "file": {
                    "path": "docs/client_reference.rst"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "4117ab43",
                "new_commit_hash": "b0bbe769",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/docs/client_reference.rst"
            },
            "plus_file": {
                "path": "b/docs/client_reference.rst"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 100,
                            "length": 9
                        },
                        "new_range": {
                            "start": 100,
                            "length": 11
                        },
                        "section": "The client session supports the context manager protocol for self closing."
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "   :param aiohttp.BasicAuth auth: an object that represents HTTP Basic",
                                "type": "context"
                            },
                            {
                                "content": "                                  Authorization (optional). It will be included",
                                "type": "context"
                            },
                            {
                                "content": "                                  with any request to any origin and will not be",
                                "type": "deleted"
                            },
                            {
                                "content": "                                  removed, event during redirect to a different",
                                "type": "deleted"
                            },
                            {
                                "content": "                                  origin.",
                                "type": "deleted"
                            },
                            {
                                "content": "                                  with any request. However, if the",
                                "type": "added"
                            },
                            {
                                "content": "                                  ``_base_url`` parameter is set, the request",
                                "type": "added"
                            },
                            {
                                "content": "                                  URL's origin must match the base URL's origin;",
                                "type": "added"
                            },
                            {
                                "content": "                                  otherwise, the default auth will not be",
                                "type": "added"
                            },
                            {
                                "content": "                                  included.",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "   :param version: supported HTTP version, ``HTTP 1.1`` by default.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "# HTTP client functional tests against aiohttp.web server\n\nimport asyncio\nimport datetime\nimport http.cookies\nimport io\nimport json\nimport pathlib\nimport socket\nimport ssl\nimport sys\nimport tarfile\nimport time\nimport zipfile\nfrom typing import (\n    Any,\n    AsyncIterator,\n    Awaitable,\n    Callable,\n    Dict,\n    List,\n    NoReturn,\n    Optional,\n    Type,\n    Union,\n)\nfrom unittest import mock\n\nimport pytest\nimport trustme\nfrom multidict import MultiDict\nfrom pytest_mock import MockerFixture\nfrom yarl import URL\n\nimport aiohttp\nfrom aiohttp import Fingerprint, ServerFingerprintMismatch, hdrs, web\nfrom aiohttp.abc import AbstractResolver, ResolveResult\nfrom aiohttp.client_exceptions import (\n    InvalidURL,\n    InvalidUrlClientError,\n    InvalidUrlRedirectClientError,\n    NonHttpUrlClientError,\n    NonHttpUrlRedirectClientError,\n    SocketTimeoutError,\n    TooManyRedirects,\n)\nfrom aiohttp.pytest_plugin import AiohttpClient, AiohttpServer\nfrom aiohttp.test_utils import TestClient, TestServer, unused_port\nfrom aiohttp.typedefs import Handler\n\n\n@pytest.fixture\ndef here() -> pathlib.Path:\n    return pathlib.Path(__file__).parent\n\n\n@pytest.fixture\ndef fname(here: pathlib.Path) -> pathlib.Path:\n    return here / \"conftest.py\"\n\n\nasync def test_keepalive_two_requests_success(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_keepalive_after_head_requests_success(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    app.router.add_route(\"HEAD\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.head(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert 1 == cnt_conn_reuse\n\n\n@pytest.mark.parametrize(\"status\", (101, 204, 304))\nasync def test_keepalive_after_empty_body_status(\n    aiohttp_client: AiohttpClient, status: int\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(status=status)\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert cnt_conn_reuse == 1\n\n\n@pytest.mark.parametrize(\"status\", (101, 204, 304))\nasync def test_keepalive_after_empty_body_status_stream_response(\n    aiohttp_client: AiohttpClient, status: int\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        stream_response = web.StreamResponse(status=status)\n        await stream_response.prepare(request)\n        return stream_response\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert cnt_conn_reuse == 1\n\n\nasync def test_keepalive_response_released(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    resp1.release()\n    resp2 = await client.get(\"/\")\n    resp2.release()\n\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_upgrade_connection_not_released_after_read(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(\n            status=101, headers={\"Connection\": \"Upgrade\", \"Upgrade\": \"tcp\"}\n        )\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    await resp.read()\n    assert resp.connection is not None\n    assert not resp.closed\n\n\nasync def test_keepalive_server_force_close_connection(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        response = web.Response(body=b\"OK\")\n        response.force_close()\n        return response\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    resp1.close()\n    resp2 = await client.get(\"/\")\n    resp2.close()\n\n    assert client._session.connector is not None\n    assert 0 == len(client._session.connector._conns)\n\n\nasync def test_keepalive_timeout_async_sleep() -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001)\n    await runner.setup()\n\n    port = unused_port()\n    site = web.TCPSite(runner, host=\"localhost\", port=port)\n    await site.start()\n\n    try:\n        async with aiohttp.ClientSession() as sess:\n            resp1 = await sess.get(f\"http://localhost:{port}/\")\n            await resp1.read()\n            # wait for server keepalive_timeout\n            await asyncio.sleep(0.01)\n            resp2 = await sess.get(f\"http://localhost:{port}/\")\n            await resp2.read()\n    finally:\n        await asyncio.gather(runner.shutdown(), site.stop())\n\n\n@pytest.mark.skipif(\n    sys.version_info[:2] == (3, 11),\n    reason=\"https://github.com/pytest-dev/pytest/issues/10763\",\n)\nasync def test_keepalive_timeout_sync_sleep() -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001)\n    await runner.setup()\n\n    port = unused_port()\n    site = web.TCPSite(runner, host=\"localhost\", port=port)\n    await site.start()\n\n    try:\n        async with aiohttp.ClientSession() as sess:\n            resp1 = await sess.get(f\"http://localhost:{port}/\")\n            await resp1.read()\n            # wait for server keepalive_timeout\n            # time.sleep is a more challenging scenario than asyncio.sleep\n            time.sleep(0.01)\n            resp2 = await sess.get(f\"http://localhost:{port}/\")\n            await resp2.read()\n    finally:\n        await asyncio.gather(runner.shutdown(), site.stop())\n\n\nasync def test_release_early(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        await request.read()\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n    resp = await client.get(\"/\")\n    assert resp.closed\n    await resp.wait_for_close()\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_HTTP_304(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(status=304)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    content = await resp.read()\n    assert content == b\"\"\n\n\nasync def test_stream_request_on_server_eof(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"OK\", status=200)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    app.add_routes([web.put(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def data_gen() -> AsyncIterator[bytes]:\n        for _ in range(2):\n            yield b\"just data\"\n            await asyncio.sleep(0.1)\n\n    assert client.session.connector is not None\n    async with client.put(\"/\", data=data_gen()) as resp:\n        assert 200 == resp.status\n        assert len(client.session.connector._acquired) == 1\n        conn = next(iter(client.session.connector._acquired))\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n    # Connection should have been reused\n    conns = next(iter(client.session.connector._conns.values()))\n    assert len(conns) == 1\n    assert conns[0][0] is conn\n\n\nasync def test_stream_request_on_server_eof_nested(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"OK\", status=200)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    app.add_routes([web.put(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def data_gen() -> AsyncIterator[bytes]:\n        for _ in range(2):\n            yield b\"just data\"\n            await asyncio.sleep(0.1)\n\n    async with client.put(\"/\", data=data_gen()) as resp:\n        assert 200 == resp.status\n        async with client.get(\"/\") as resp:\n            assert 200 == resp.status\n\n    # Should be 2 separate connections\n    assert client.session.connector is not None\n    conns = next(iter(client.session.connector._conns.values()))\n    assert len(conns) == 2\n\n\nasync def test_HTTP_304_WITH_BODY(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"test\", status=304)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    content = await resp.read()\n    assert content == b\"\"\n\n\nasync def test_auto_header_user_agent(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"aiohttp\" in request.headers[\"user-agent\"]\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_auto_headers_user_agent(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.USER_AGENT not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", skip_auto_headers=[\"user-agent\"]) as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_default_auto_headers_user_agent(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.USER_AGENT not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, skip_auto_headers=[\"user-agent\"])\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_auto_headers_content_type(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.CONTENT_TYPE not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", skip_auto_headers=[\"content-type\"]) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_bytesio(aiohttp_client: AiohttpClient) -> None:\n    data = b\"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert len(data) == request.content_length\n        val = await request.read()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(data) as file_handle:\n        async with client.post(\"/\", data=file_handle) as resp:\n            assert 200 == resp.status\n\n\nasync def test_post_data_with_bytesio_file(aiohttp_client: AiohttpClient) -> None:\n    data = b\"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        post_data = await request.post()\n        assert [\"file\"] == list(post_data.keys())\n        file_field = post_data[\"file\"]\n        assert isinstance(file_field, web.FileField)\n        assert data == file_field.file.read()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(data) as file_handle:\n        async with client.post(\"/\", data={\"file\": file_handle}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_post_data_stringio(aiohttp_client: AiohttpClient) -> None:\n    data = \"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert len(data) == request.content_length\n        assert request.headers[\"CONTENT-TYPE\"] == \"text/plain; charset=utf-8\"\n        val = await request.text()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data=io.StringIO(data)) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_textio_encoding(aiohttp_client: AiohttpClient) -> None:\n    data = \"текст\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.headers[\"CONTENT-TYPE\"] == \"text/plain; charset=koi8-r\"\n        val = await request.text()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    pl = aiohttp.TextIOPayload(io.StringIO(data), encoding=\"koi8-r\")\n    async with client.post(\"/\", data=pl) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_zipfile_filelike(aiohttp_client: AiohttpClient) -> None:\n    data = b\"This is a zip file payload text file.\"\n\n    async def handler(request: web.Request) -> web.Response:\n        val = await request.read()\n        assert data == val, \"Transmitted zipfile member failed to match original data.\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    buf = io.BytesIO()\n    with zipfile.ZipFile(file=buf, mode=\"w\") as zf:\n        with zf.open(\"payload1.txt\", mode=\"w\") as zip_filelike_writing:\n            zip_filelike_writing.write(data)\n\n    buf.seek(0)\n    zf = zipfile.ZipFile(file=buf, mode=\"r\")\n    resp = await client.post(\"/\", data=zf.open(\"payload1.txt\"))\n    assert 200 == resp.status\n\n\nasync def test_post_data_tarfile_filelike(aiohttp_client: AiohttpClient) -> None:\n    data = b\"This is a tar file payload text file.\"\n\n    async def handler(request: web.Request) -> web.Response:\n        val = await request.read()\n        assert data == val, \"Transmitted tarfile member failed to match original data.\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    buf = io.BytesIO()\n    with tarfile.open(fileobj=buf, mode=\"w\") as tf:\n        ti = tarfile.TarInfo(name=\"payload1.txt\")\n        ti.size = len(data)\n        tf.addfile(tarinfo=ti, fileobj=io.BytesIO(data))\n\n    # Random-access tarfile.\n    buf.seek(0)\n    tf = tarfile.open(fileobj=buf, mode=\"r:\")\n    resp = await client.post(\"/\", data=tf.extractfile(\"payload1.txt\"))\n    assert 200 == resp.status\n\n    # Streaming tarfile.\n    buf.seek(0)\n    tf = tarfile.open(fileobj=buf, mode=\"r|\")\n    for entry in tf:\n        resp = await client.post(\"/\", data=tf.extractfile(entry))\n        assert 200 == resp.status\n\n\nasync def test_ssl_client(\n    aiohttp_server: AiohttpServer,\n    ssl_ctx: ssl.SSLContext,\n    aiohttp_client: AiohttpClient,\n    client_ssl_ctx: ssl.SSLContext,\n) -> None:\n    connector = aiohttp.TCPConnector(ssl=client_ssl_ctx)\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"Test message\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"Test message\"\n\n\nasync def test_tcp_connector_fingerprint_ok(\n    aiohttp_server: AiohttpServer,\n    aiohttp_client: AiohttpClient,\n    ssl_ctx: ssl.SSLContext,\n    tls_certificate_fingerprint_sha256: bytes,\n) -> None:\n    tls_fingerprint = Fingerprint(tls_certificate_fingerprint_sha256)\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"Test message\")\n\n    connector = aiohttp.TCPConnector(ssl=tls_fingerprint)\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_tcp_connector_fingerprint_fail(\n    aiohttp_server: AiohttpServer,\n    aiohttp_client: AiohttpClient,\n    ssl_ctx: ssl.SSLContext,\n    tls_certificate_fingerprint_sha256: bytes,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    bad_fingerprint = b\"\\x00\" * len(tls_certificate_fingerprint_sha256)\n\n    connector = aiohttp.TCPConnector(ssl=Fingerprint(bad_fingerprint))\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    with pytest.raises(ServerFingerprintMismatch) as cm:\n        await client.get(\"/\")\n    exc = cm.value\n    assert exc.expected == bad_fingerprint\n    assert exc.got == tls_certificate_fingerprint_sha256\n\n\nasync def test_format_task_get(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app)\n    client = aiohttp.ClientSession()\n    task = asyncio.create_task(client.get(server.make_url(\"/\")))\n    assert f\"{task}\".startswith(\"<Task pending\")\n    resp = await task\n    resp.close()\n    await client.close()\n\n\nasync def test_str_params(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"q=t est\" in request.rel_url.query_string\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", params=\"q=t+est\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_drop_params_on_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok?a=redirect\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        assert request.rel_url.query_string == \"a=redirect\"\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\", params={\"a\": \"initial\"}) as resp:\n        assert resp.status == 200\n\n\nasync def test_drop_fragment_on_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok#fragment\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\") as resp:\n        assert resp.status == 200\n        assert resp.url.path == \"/ok\"\n\n\nasync def test_drop_fragment(aiohttp_client: AiohttpClient) -> None:\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/ok#fragment\") as resp:\n        assert resp.status == 200\n        assert resp.url.path == \"/ok\"\n\n\nasync def test_history(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/ok\") as resp:\n        assert len(resp.history) == 0\n        assert resp.status == 200\n\n    async with client.get(\"/redirect\") as resp_redirect:\n        assert len(resp_redirect.history) == 1\n        assert resp_redirect.history[0].status == 301\n        assert resp_redirect.status == 200\n\n\nasync def test_keepalive_closed_by_server(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        resp = web.Response(body=b\"OK\")\n        resp.force_close()\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    val1 = await resp1.read()\n    assert val1 == b\"OK\"\n    resp2 = await client.get(\"/\")\n    val2 = await resp2.read()\n    assert val2 == b\"OK\"\n\n    assert client._session.connector is not None\n    assert 0 == len(client._session.connector._conns)\n\n\nasync def test_wait_for(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await asyncio.wait_for(client.get(\"/\"), 10)\n    assert resp.status == 200\n    txt = await resp.text()\n    assert txt == \"OK\"\n\n\nasync def test_raw_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n        raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers)\n        assert raw_headers == (\n            (b\"Content-Length\", b\"0\"),\n            (b\"Date\", mock.ANY),\n            (b\"Server\", mock.ANY),\n        )\n\n\nasync def test_host_header_first(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert list(request.headers)[0] == hdrs.HOST\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_empty_header_values(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response()\n        resp.headers[\"X-Empty\"] = \"\"\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n        raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers)\n        assert raw_headers == (\n            (b\"X-Empty\", b\"\"),\n            (b\"Content-Length\", b\"0\"),\n            (b\"Date\", mock.ANY),\n            (b\"Server\", mock.ANY),\n        )\n\n\nasync def test_204_with_gzipped_content_encoding(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=204)\n        resp.content_length = 0\n        resp.content_type = \"application/json\"\n        # resp.enable_compression(web.ContentCoding.gzip)\n        resp.headers[\"Content-Encoding\"] = \"gzip\"\n        await resp.prepare(request)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"DELETE\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.delete(\"/\") as resp:\n        assert resp.status == 204\n        assert resp.closed\n\n\nasync def test_timeout_on_reading_headers(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\", timeout=aiohttp.ClientTimeout(total=0.01))\n\n\nasync def test_timeout_on_conn_reading_headers(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    # tests case where user did not set a connection timeout\n\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    conn = aiohttp.TCPConnector()\n    client = await aiohttp_client(app, connector=conn)\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\", timeout=aiohttp.ClientTimeout(total=0.01))\n\n\nasync def test_timeout_on_session_read_timeout(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    conn = aiohttp.TCPConnector()\n    client = await aiohttp_client(\n        app, connector=conn, timeout=aiohttp.ClientTimeout(sock_read=0.01)\n    )\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_read_timeout_between_chunks(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        # write data 4 times, with pauses. Total time 2 seconds.\n        for _ in range(4):\n            await asyncio.sleep(0.5)\n            await resp.write(b\"data\\n\")\n        return resp\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    # A timeout of 0.2 seconds should apply per read.\n    timeout = aiohttp.ClientTimeout(sock_read=1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    res = b\"\"\n    async with await client.get(\"/\") as resp:\n        res += await resp.read()\n\n    assert res == b\"data\\n\" * 4\n\n\nasync def test_read_timeout_on_reading_chunks(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        await resp.write(b\"data\\n\")\n        await asyncio.sleep(1)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    # A timeout of 0.2 seconds should apply per read.\n    timeout = aiohttp.ClientTimeout(sock_read=0.2)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    async with await client.get(\"/\") as resp:\n        assert (await resp.content.read(5)) == b\"data\\n\"\n        with pytest.raises(asyncio.TimeoutError):\n            await resp.content.read()\n\n\nasync def test_read_timeout_on_write(aiohttp_client: AiohttpClient) -> None:\n    async def gen_payload() -> AsyncIterator[bytes]:\n        # Delay writing to ensure read timeout isn't triggered before writing completes.\n        await asyncio.sleep(0.5)\n        yield b\"foo\"\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=await request.read())\n\n    app = web.Application()\n    app.router.add_put(\"/\", handler)\n\n    timeout = aiohttp.ClientTimeout(total=None, sock_read=0.1)\n    client = await aiohttp_client(app)\n    async with client.put(\"/\", data=gen_payload(), timeout=timeout) as resp:\n        result = await resp.read()  # Should not trigger a read timeout.\n    assert result == b\"foo\"\n\n\nasync def test_timeout_on_reading_data(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    loop = asyncio.get_event_loop()\n\n    fut = loop.create_future()\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        fut.set_result(None)\n        await asyncio.sleep(0.2)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", timeout=aiohttp.ClientTimeout(1))\n    await fut\n\n    with pytest.raises(asyncio.TimeoutError):\n        await resp.read()\n\n\nasync def test_timeout_none(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", timeout=None) as resp:\n        assert resp.status == 200\n\n\nasync def test_readline_error_on_conn_close(aiohttp_client: AiohttpClient) -> None:\n    loop = asyncio.get_event_loop()\n\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n\n        # make sure connection is closed by client.\n        with pytest.raises(aiohttp.ServerDisconnectedError):\n            for _ in range(10):\n                await resp.write(b\"data\\n\")\n                await asyncio.sleep(0.5)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        timer_started = False\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        with pytest.raises(aiohttp.ClientConnectionError):\n            while True:\n                data = await resp.content.readline()\n                data = data.strip()\n                assert data\n                assert data == b\"data\"\n                if not timer_started:\n                    loop.call_later(1.0, resp.release)\n                    timer_started = True\n    finally:\n        await session.close()\n\n\nasync def test_no_error_on_conn_close_if_eof(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp_ = web.StreamResponse()\n        await resp_.prepare(request)\n        await resp_.write(b\"data\\n\")\n        await asyncio.sleep(0.5)\n        return resp_\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        while True:\n            data = await resp.content.readline()\n            data = data.strip()\n            if not data:\n                break\n            assert data == b\"data\"\n\n        assert resp.content.exception() is None\n    finally:\n        await session.close()\n\n\nasync def test_error_not_overwrote_on_conn_close(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp_ = web.StreamResponse()\n        await resp_.prepare(request)\n        return resp_\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        resp.content.set_exception(ValueError())\n    finally:\n        await session.close()\n\n    assert isinstance(resp.content.exception(), ValueError)\n\n\nasync def test_HTTP_200_OK_METHOD(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n\n    client = await aiohttp_client(app)\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        resp = await client.request(meth, \"/\")\n        assert resp.status == 200\n        assert len(resp.history) == 0\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_HTTP_200_OK_METHOD_connector(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    conn = aiohttp.TCPConnector()\n    conn.clear_dns_cache()\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n    client = await aiohttp_client(app, connector=conn)\n\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\"):\n        resp = await client.request(meth, \"/\")\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        assert resp.status == 200\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_HTTP_302_REDIRECT_GET(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\") as resp:\n        assert 200 == resp.status\n        assert 1 == len(resp.history)\n\n\nasync def test_HTTP_302_REDIRECT_HEAD(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n    app.router.add_head(\"/\", handler)\n    app.router.add_head(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    async with client.request(\"head\", \"/redirect\") as resp:\n        assert 200 == resp.status\n        assert 1 == len(resp.history)\n        assert resp.method == \"HEAD\"\n\n\nasync def test_HTTP_302_REDIRECT_NON_HTTP(aiohttp_client: AiohttpClient) -> None:\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"ftp://127.0.0.1/test/\")\n\n    app = web.Application()\n    app.router.add_get(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(NonHttpUrlRedirectClientError):\n        await client.get(\"/redirect\")\n\n\nasync def test_HTTP_302_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\")\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"GET\"\n    resp.close()\n\n\nasync def test_HTTP_302_REDIRECT_POST_with_content_length_hdr(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPFound(location=\"/\")\n\n    data = json.dumps({\"some\": \"data\"})\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\n        \"/redirect\", data=data, headers={\"Content-Length\": str(len(data))}\n    )\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"GET\"\n    resp.close()\n\n\nasync def test_HTTP_307_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPTemporaryRedirect(location=\"/\")\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"POST\"\n    resp.close()\n\n\nasync def test_HTTP_308_PERMANENT_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPPermanentRedirect(location=\"/\")\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"POST\"\n    resp.close()\n\n\nasync def test_HTTP_302_max_redirects(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    async def redirect(request: web.Request) -> NoReturn:\n        count = int(request.match_info[\"count\"])\n        assert count\n        raise web.HTTPFound(location=f\"/redirect/{count - 1}\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(r\"/redirect/{count:\\d+}\", redirect)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(TooManyRedirects) as ctx:\n        await client.get(\"/redirect/5\", max_redirects=2)\n    assert 2 == len(ctx.value.history)\n    assert ctx.value.request_info.url.path == \"/redirect/5\"\n    assert ctx.value.request_info.method == \"GET\"\n\n\nasync def test_HTTP_200_GET_WITH_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", params={\"q\": \"test\"})\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"q=test\"\n    resp.close()\n\n\nasync def test_HTTP_200_GET_WITH_MultiDict_PARAMS(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", params=MultiDict([(\"q\", \"test\"), (\"q\", \"test2\")]))\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"q=test&q=test2\"\n    resp.close()\n\n\nasync def test_HTTP_200_GET_WITH_MIXED_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/?test=true\", params={\"q\": \"test\"})\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"test=true&q=test\"\n    resp.close()\n\n\nasync def test_POST_DATA(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n\nasync def test_POST_DATA_with_explicit_formdata(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"text\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"name\": \"text\"}\n    resp.close()\n\n\nasync def test_POST_DATA_with_charset(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        mp = await request.multipart()\n        part = await mp.next()\n        assert isinstance(part, aiohttp.BodyPartReader)\n        text = await part.text()\n        return web.Response(text=text)\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"текст\", content_type=\"text/plain; charset=koi8-r\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_DATA_formdats_with_charset(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        mp = await request.post()\n        assert \"name\" in mp\n        assert isinstance(mp[\"name\"], str)\n        return web.Response(text=mp[\"name\"])\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData(charset=\"koi8-r\")\n    form.add_field(\"name\", \"текст\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_DATA_with_charset_post(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"name\"], str)\n        return web.Response(text=data[\"name\"])\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"текст\", content_type=\"text/plain; charset=koi8-r\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_MultiDict(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data == MultiDict([(\"q\", \"test1\"), (\"q\", \"test2\")])\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\n        \"/\", data=MultiDict([(\"q\", \"test1\"), (\"q\", \"test2\")])\n    ) as resp:\n        assert 200 == resp.status\n\n\nasync def test_POST_DATA_DEFLATE(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    # True is not a valid type, but still tested for backwards compatibility.\n    resp = await client.post(\"/\", data={\"some\": \"data\"}, compress=True)  # type: ignore[arg-type]\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n\nasync def test_POST_FILES(aiohttp_client: AiohttpClient, fname: pathlib.Path) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            content1 = f.read()\n        content2 = data[\"some\"].file.read()\n        assert content1 == content2\n        assert isinstance(data[\"test\"], web.FileField)\n        assert data[\"test\"].file.read() == b\"data\"\n        assert isinstance(data[\"some\"], web.FileField)\n        data[\"some\"].file.close()\n        data[\"test\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data={\"some\": f, \"test\": io.BytesIO(b\"data\")}, chunked=True\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_DEFLATE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            content1 = f.read()\n        content2 = data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        assert content1 == content2\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data={\"some\": f}, chunked=True, compress=\"deflate\"\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_bytes(aiohttp_client: AiohttpClient) -> None:\n    body = b\"0\" * 12345\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        assert body == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data=body) as resp:\n        assert 200 == resp.status\n\n\nasync def test_POST_bytes_too_large(aiohttp_client: AiohttpClient) -> None:\n    body = b\"0\" * (2**20 + 1)\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.content.read()\n        assert body == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.warns(ResourceWarning):\n        resp = await client.post(\"/\", data=body)\n\n    assert 200 == resp.status\n    resp.close()\n\n\nasync def test_POST_FILES_STR(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        with fname.open(\"rb\") as f:\n            content1 = f.read().decode()\n        content2 = data[\"some\"]\n        assert content1 == content2\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data={\"some\": f.read().decode()}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_STR_SIMPLE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f.read()) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_LIST(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert fname.name == data[\"some\"].filename\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=[(\"some\", f)]) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_CT(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert fname.name == data[\"some\"].filename\n        assert \"text/plain\" == data[\"some\"].content_type\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        form = aiohttp.FormData()\n        form.add_field(\"some\", f, content_type=\"text/plain\")\n        async with client.post(\"/\", data=form) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.text()\n        with fname.open(\"rb\") as f:\n            content = f.read().decode()\n            assert content == data\n        # if system cannot determine 'text/x-python' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"text/plain\",\n            \"application/octet-stream\",\n            \"text/x-python\",\n        ]\n        assert \"content-disposition\" not in request.headers\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE_content_disposition(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.text()\n        with fname.open(\"rb\") as f:\n            content = f.read().decode()\n            assert content == data\n        # if system cannot determine 'application/pgp-keys' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"text/plain\",\n            \"application/octet-stream\",\n            \"text/x-python\",\n        ]\n        assert request.headers[\"content-disposition\"] == (\n            'inline; filename=\"conftest.py\"'\n        )\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data=aiohttp.get_payload(f, disposition=\"inline\")\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE_BINARY(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data\n        # if system cannot determine 'application/pgp-keys' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"application/pgp-keys\",\n            \"text/plain\",\n            \"text/x-python\",\n            \"application/octet-stream\",\n        ]\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_IO(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"unknown\"], web.FileField)\n        assert b\"data\" == data[\"unknown\"].file.read()\n        assert data[\"unknown\"].content_type == \"application/octet-stream\"\n        assert data[\"unknown\"].filename == \"unknown\"\n        data[\"unknown\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(b\"data\") as file_handle:\n        async with client.post(\"/\", data=[file_handle]) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_IO_WITH_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data[\"test\"] == \"true\"\n        assert isinstance(data[\"unknown\"], web.FileField)\n        assert data[\"unknown\"].content_type == \"application/octet-stream\"\n        assert data[\"unknown\"].filename == \"unknown\"\n        assert data[\"unknown\"].file.read() == b\"data\"\n        data[\"unknown\"].file.close()\n        assert data.getall(\"q\") == [\"t1\", \"t2\"]\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(b\"data\") as file_handle:\n        async with client.post(\n            \"/\",\n            data=((\"test\", \"true\"), MultiDict([(\"q\", \"t1\"), (\"q\", \"t2\")]), file_handle),\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_WITH_DATA(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data[\"test\"] == \"true\"\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].content_type in [\n            \"text/x-python\",\n            \"text/plain\",\n            \"application/octet-stream\",\n        ]\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            assert data[\"some\"].file.read() == f.read()\n            data[\"some\"].file.close()\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data={\"test\": \"true\", \"some\": f}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_STREAM_DATA(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/octet-stream\"\n        content = await request.read()\n        with fname.open(\"rb\") as f:\n            expected = f.read()\n            assert request.content_length == len(expected)\n            assert content == expected\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        data_size = len(f.read())\n\n    async def gen(fname: pathlib.Path) -> AsyncIterator[bytes]:\n        with fname.open(\"rb\") as f:\n            data = f.read(100)\n            while data:\n                yield data\n                data = f.read(100)\n\n    async with client.post(\n        \"/\", data=gen(fname), headers={\"Content-Length\": str(data_size)}\n    ) as resp:\n        assert 200 == resp.status\n\n\nasync def test_json(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/json\"\n        data = await request.json()\n        return web.Response(body=aiohttp.JsonPayload(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/\", json={\"some\": \"data\"})\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n    with pytest.raises(ValueError):\n        await client.post(\"/\", data=\"some data\", json={\"some\": \"data\"})\n\n\nasync def test_json_custom(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/json\"\n        data = await request.json()\n        return web.Response(body=aiohttp.JsonPayload(data))\n\n    used = False\n\n    def dumps(obj: Any) -> str:\n        nonlocal used\n        used = True\n        return json.dumps(obj)\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app, json_serialize=dumps)\n\n    resp = await client.post(\"/\", json={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert used\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n    with pytest.raises(ValueError):\n        await client.post(\"/\", data=\"some data\", json={\"some\": \"data\"})\n\n\nasync def test_expect_continue(aiohttp_client: AiohttpClient) -> None:\n    expect_called = False\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data == {\"some\": \"data\"}\n        return web.Response()\n\n    async def expect_handler(request: web.Request) -> None:\n        nonlocal expect_called\n        expect = request.headers[hdrs.EXPECT]\n        assert expect.lower() == \"100-continue\"\n        assert request.transport is not None\n        request.transport.write(b\"HTTP/1.1 100 Continue\\r\\n\\r\\n\")\n        expect_called = True\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler, expect_handler=expect_handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data={\"some\": \"data\"}, expect100=True) as resp:\n        assert 200 == resp.status\n    assert expect_called\n\n\nasync def test_encoding_deflate(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        resp.enable_compression(web.ContentCoding.deflate)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_deflate_nochunk(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_compression(web.ContentCoding.deflate)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_gzip(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        resp.enable_compression(web.ContentCoding.gzip)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_gzip_write_by_chunks(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        resp.enable_compression(web.ContentCoding.gzip)\n        await resp.prepare(request)\n        await resp.write(b\"0\")\n        await resp.write(b\"0\")\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"00\"\n    resp.close()\n\n\nasync def test_encoding_gzip_nochunk(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_compression(web.ContentCoding.gzip)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_bad_payload_compression(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.headers[\"Content-Encoding\"] = \"gzip\"\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_bad_payload_chunked_encoding(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        resp.force_close()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write(b\"9\\r\\n\\r\\n\")\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_no_payload_304_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test a 304 response with no payload with chunked set should have it removed.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=304)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING not in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_head_request_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test a head response with chunked set should have it removed.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=200)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_head(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.head(\"/\")\n    assert resp.status == 200\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING not in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_no_payload_200_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test chunked is preserved on a 200 response with no payload.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=200)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 200\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_bad_payload_content_length(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.headers[\"Content-Length\"] = \"10000\"\n        resp.force_close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_payload_content_length_by_chunks(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"2\"})\n        await resp.prepare(request)\n        await resp.write(b\"answer\")\n        await resp.write(b\"two\")\n        assert request.transport is not None\n        request.transport.close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    data = await resp.read()\n    assert data == b\"an\"\n    resp.close()\n\n\nasync def test_chunked(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    assert resp.headers[\"Transfer-Encoding\"] == \"chunked\"\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_shortcuts(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n    client = await aiohttp_client(app)\n\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        coro = getattr(client.session, meth)\n        resp = await coro(client.make_url(\"/\"))\n\n        assert resp.status == 200\n        assert len(resp.history) == 0\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_cookies(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test1\", \"test3\"}\n        assert request.cookies[\"test1\"] == \"123\"\n        assert request.cookies[\"test3\"] == \"456\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test1\": \"123\", \"test2\": c})\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_per_request(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test1\", \"test3\", \"test4\", \"test6\"}\n        assert request.cookies[\"test1\"] == \"123\"\n        assert request.cookies[\"test3\"] == \"456\"\n        assert request.cookies[\"test4\"] == \"789\"\n        assert request.cookies[\"test6\"] == \"abc\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test1\": \"123\", \"test2\": c})\n\n    rc: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    rc.set(\"test6\", \"abc\", \"abc\")\n\n    cookies: Dict[str, Union[str, \"http.cookies.Morsel[str]\"]]\n    cookies = {\"test4\": \"789\", \"test5\": rc}\n    async with client.get(\"/\", cookies=cookies) as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def redirect1(request: web.Request) -> web.Response:\n        ret = web.Response(status=301, headers={\"Location\": \"/redirect2\"})\n        ret.set_cookie(\"c\", \"1\")\n        return ret\n\n    async def redirect2(request: web.Request) -> web.Response:\n        ret = web.Response(status=301, headers={\"Location\": \"/\"})\n        ret.set_cookie(\"c\", \"2\")\n        return ret\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"c\"}\n        assert request.cookies[\"c\"] == \"2\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/redirect1\", redirect1)\n    app.router.add_get(\"/redirect2\", redirect2)\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/redirect1\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_on_empty_session_jar(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"custom-cookie\" in request.cookies\n        assert request.cookies[\"custom-cookie\"] == \"abc\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies=None)\n\n    async with client.get(\"/\", cookies={\"custom-cookie\": \"abc\"}) as resp:\n        assert 200 == resp.status\n\n\nasync def test_morsel_with_attributes(aiohttp_client: AiohttpClient) -> None:\n    # A comment from original test:\n    #\n    # No cookie attribute should pass here\n    # they are only used as filters\n    # whether to send particular cookie or not.\n    # E.g. if cookie expires it just becomes thrown away.\n    # Server who sent the cookie with some attributes\n    # already knows them, no need to send this back again and again\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test3\"}\n        assert request.cookies[\"test3\"] == \"456\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n    c[\"httponly\"] = True\n    c[\"secure\"] = True\n    c[\"max-age\"] = 1000\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test2\": c})\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_set_cookies(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"ISAWPLB{A7F52349-3531-4DA9-8776-F74BC6F4F1BB}=\"\n            \"{925EC0B8-CB17-4BEB-8A35-1033813B0523}; \"\n            \"HttpOnly; Path=/\",\n        )\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with mock.patch(\"aiohttp.client_reqrep.client_logger\") as m_log:\n        async with client.get(\"/\") as resp:\n            assert 200 == resp.status\n            cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\"}\n\n        m_log.warning.assert_called_with(\"Can not load response cookies: %s\", mock.ANY)\n\n\nasync def test_set_cookies_expired(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"c3=cookie3; HttpOnly; Path=/ Expires=Tue, 1 Jan 1980 12:00:00 GMT; \",\n        )\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        cookie_names = {c.key for c in client.session.cookie_jar}\n    assert cookie_names == {\"c1\", \"c2\"}\n\n\nasync def test_set_cookies_max_age(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\"Set-Cookie\", \"c3=cookie3; HttpOnly; Path=/ Max-Age=1; \")\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\", \"c3\"}\n        await asyncio.sleep(2)\n        cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\"}\n\n\nasync def test_set_cookies_max_age_overflow(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"overflow=overflow; HttpOnly; Path=/ Max-Age=\" + str(overflow) + \"; \",\n        )\n        return ret\n\n    overflow = int(\n        datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()\n    )\n    empty = None\n    try:\n        empty = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(\n            seconds=overflow\n        )\n    except OverflowError as ex:\n        assert isinstance(ex, OverflowError)\n    assert not isinstance(empty, datetime.datetime)\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        for cookie in client.session.cookie_jar:\n            assert cookie.key == \"overflow\"\n            assert int(cookie[\"max-age\"]) == int(overflow)\n\n\nasync def test_request_conn_error() -> None:\n    client = aiohttp.ClientSession()\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"http://0.0.0.0:1\")\n    await client.close()\n\n\n@pytest.mark.xfail\nasync def test_broken_connection(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.transport is not None\n        request.transport.close()\n        return web.Response(text=\"answer\" * 1000)\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_broken_connection_2(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"1000\"})\n        await resp.prepare(request)\n        await resp.write(b\"answer\")\n        assert request.transport is not None\n        request.transport.close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n    resp.close()\n\n\nasync def test_custom_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.headers[\"x-api-key\"] == \"foo\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\n        \"/\", headers={\"Content-Type\": \"application/json\", \"x-api-key\": \"foo\"}\n    ) as resp:\n        assert resp.status == 200\n\n\nasync def test_redirect_to_absolute_url(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=client.make_url(\"/\"))\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/redirect\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_redirect_without_location_header(aiohttp_client: AiohttpClient) -> None:\n    body = b\"redirect\"\n\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, body=body)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/redirect\")\n    data = await resp.read()\n    assert data == body\n\n\nINVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW = (\n    # yarl.URL.__new__ raises ValueError\n    (\"http://:/\", \"http://:/\"),\n    (\"http://example.org:non_int_port/\", \"http://example.org:non_int_port/\"),\n)\n\nINVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN = (\n    # # yarl.URL.origin raises ValueError\n    (\"http:/\", \"http:///\"),\n    (\"http:/example.com\", \"http:///example.com\"),\n    (\"http:///example.com\", \"http:///example.com\"),\n)\n\nNON_HTTP_URL_WITH_ERROR_MESSAGE = (\n    (\"call:+380123456789\", r\"call:\\+380123456789\"),\n    (\"skype:handle\", \"skype:handle\"),\n    (\"slack://instance/room\", \"slack://instance/room\"),\n    (\"steam:code\", \"steam:code\"),\n    (\"twitter://handle\", \"twitter://handle\"),\n    (\"bluesky://profile/d:i:d\", \"bluesky://profile/d:i:d\"),\n)\n\n\n@pytest.mark.parametrize(\n    (\"url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, InvalidUrlClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n        ),\n        *(\n            (url, message, NonHttpUrlClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_and_non_http_url(\n    url: str, error_message_url: str, expected_exception_class: Type[Exception]\n) -> None:\n    async with aiohttp.ClientSession() as http_session:\n        with pytest.raises(\n            expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n        ):\n            await http_session.get(url)\n\n\n@pytest.mark.parametrize(\n    (\"invalid_redirect_url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlRedirectClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n            + INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, NonHttpUrlRedirectClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_redirect_url(\n    aiohttp_client: AiohttpClient,\n    invalid_redirect_url: str,\n    error_message_url: str,\n    expected_exception_class: Type[Exception],\n) -> None:\n    headers = {hdrs.LOCATION: invalid_redirect_url}\n\n    async def generate_redirecting_response(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers=headers)\n\n    app = web.Application()\n    app.router.add_get(\"/redirect\", generate_redirecting_response)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n    ):\n        await client.get(\"/redirect\")\n\n\n@pytest.mark.parametrize(\n    (\"invalid_redirect_url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlRedirectClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n            + INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, NonHttpUrlRedirectClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_redirect_url_multiple_redirects(\n    aiohttp_client: AiohttpClient,\n    invalid_redirect_url: str,\n    error_message_url: str,\n    expected_exception_class: Type[Exception],\n) -> None:\n    app = web.Application()\n\n    for path, location in [\n        (\"/redirect\", \"/redirect1\"),\n        (\"/redirect1\", \"/redirect2\"),\n        (\"/redirect2\", invalid_redirect_url),\n    ]:\n\n        async def generate_redirecting_response(request: web.Request) -> web.Response:\n            return web.Response(status=301, headers={hdrs.LOCATION: location})\n\n        app.router.add_get(path, generate_redirecting_response)\n\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n    ):\n        await client.get(\"/redirect\")\n\n\n@pytest.mark.parametrize(\n    (\"status\", \"expected_ok\"),\n    (\n        (200, True),\n        (201, True),\n        (301, True),\n        (400, False),\n        (403, False),\n        (500, False),\n    ),\n)\nasync def test_ok_from_status(\n    aiohttp_client: AiohttpClient, status: int, expected_ok: bool\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=status, body=b\"\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/endpoint\", handler)\n    client = await aiohttp_client(app, raise_for_status=False)\n    async with client.get(\"/endpoint\") as resp:\n        assert resp.ok is expected_ok\n\n\nasync def test_raise_for_status(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, raise_for_status=True)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_raise_for_status_per_request(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\", raise_for_status=True)\n\n\nasync def test_raise_for_status_disable_per_request(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, raise_for_status=True)\n\n    async with client.get(\"/\", raise_for_status=False) as resp:\n        assert 400 == resp.status\n\n\nasync def test_request_raise_for_status_default(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.request(\"GET\", server.make_url(\"/\")) as resp:\n        assert resp.status == 400\n\n\nasync def test_request_raise_for_status_disabled(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n    url = server.make_url(\"/\")\n\n    async with aiohttp.request(\"GET\", url, raise_for_status=False) as resp:\n        assert resp.status == 400\n\n\nasync def test_request_raise_for_status_enabled(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n    url = server.make_url(\"/\")\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        async with aiohttp.request(\"GET\", url, raise_for_status=True):\n            assert False, \"never executed\"  # pragma: no cover\n\n\nasync def test_session_raise_for_status_coro(aiohttp_client: AiohttpClient) -> None:\n    async def handle(request: web.Request) -> web.Response:\n        return web.Response(text=\"ok\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handle)\n\n    raise_for_status_called = 0\n\n    async def custom_r4s(response: aiohttp.ClientResponse) -> None:\n        nonlocal raise_for_status_called\n        raise_for_status_called += 1\n        assert response.status == 200\n        assert response.request_info.method == \"GET\"\n\n    client = await aiohttp_client(app, raise_for_status=custom_r4s)\n    await client.get(\"/\")\n    assert raise_for_status_called == 1\n    await client.get(\"/\", raise_for_status=True)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n    await client.get(\"/\", raise_for_status=False)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n\n\nasync def test_request_raise_for_status_coro(aiohttp_client: AiohttpClient) -> None:\n    async def handle(request: web.Request) -> web.Response:\n        return web.Response(text=\"ok\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handle)\n\n    raise_for_status_called = 0\n\n    async def custom_r4s(response: aiohttp.ClientResponse) -> None:\n        nonlocal raise_for_status_called\n        raise_for_status_called += 1\n        assert response.status == 200\n        assert response.request_info.method == \"GET\"\n\n    client = await aiohttp_client(app)\n    await client.get(\"/\", raise_for_status=custom_r4s)\n    assert raise_for_status_called == 1\n    await client.get(\"/\", raise_for_status=True)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n    await client.get(\"/\", raise_for_status=False)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n\n\nasync def test_invalid_idna() -> None:\n    session = aiohttp.ClientSession()\n    try:\n        with pytest.raises(aiohttp.InvalidURL):\n            await session.get(\"http://\\u2061owhefopw.com\")\n    finally:\n        await session.close()\n\n\nasync def test_creds_in_auth_and_url() -> None:\n    session = aiohttp.ClientSession()\n    try:\n        with pytest.raises(ValueError):\n            await session.get(\n                \"http://user:pass@example.com\", auth=aiohttp.BasicAuth(\"user2\", \"pass2\")\n            )\n    finally:\n        await session.close()\n\n\n@pytest.fixture\ndef create_server_for_url_and_handler(\n    aiohttp_server: AiohttpServer, tls_certificate_authority: trustme.CA\n) -> Callable[[URL, Handler], Awaitable[TestServer]]:\n    def create(url: URL, srv: Handler) -> Awaitable[TestServer]:\n        app = web.Application()\n        app.router.add_route(\"GET\", url.path, srv)\n\n        if url.scheme == \"https\":\n            assert url.host\n            cert = tls_certificate_authority.issue_cert(\n                url.host, \"localhost\", \"127.0.0.1\"\n            )\n            ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n            cert.configure_cert(ssl_ctx)\n            return aiohttp_server(app, ssl=ssl_ctx)\n        return aiohttp_server(app)\n\n    return create\n\n\n@pytest.mark.parametrize(\n    [\"url_from_s\", \"url_to_s\", \"is_drop_header_expected\"],\n    [\n        [\n            \"http://host1.com/path1\",\n            \"http://host2.com/path2\",\n            True,\n        ],\n        [\"http://host1.com/path1\", \"https://host1.com/path1\", False],\n        [\"https://host1.com/path1\", \"http://host1.com/path2\", True],\n    ],\n    ids=(\n        \"entirely different hosts\",\n        \"http -> https\",\n        \"https -> http\",\n    ),\n)\nasync def test_drop_auth_on_redirect_to_other_host(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n    url_from_s: str,\n    url_to_s: str,\n    is_drop_header_expected: bool,\n) -> None:\n    url_from, url_to = URL(url_from_s), URL(url_to_s)\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        if is_drop_header_expected:\n            assert \"Authorization\" not in request.headers, \"Header wasn't dropped\"\n        else:\n            assert \"Authorization\" in request.headers, \"Header was dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(connector=connector) as client:\n        resp = await client.get(\n            url_from,\n            auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n        )\n        assert resp.status == 200\n        resp = await client.get(\n            url_from,\n            headers={\"Authorization\": \"Basic dXNlcjpwYXNz\"},\n        )\n        assert resp.status == 200\n\n\nasync def test_async_with_session() -> None:\n    async with aiohttp.ClientSession() as session:\n        pass\n\n    assert session.closed\n\n\nasync def test_session_close_awaitable() -> None:\n    session = aiohttp.ClientSession()\n    await session.close()\n\n    assert session.closed\n\n\nasync def test_close_resp_on_error_async_with_session(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.ClientSession() as session:\n        with pytest.raises(RuntimeError):\n            async with session.get(server.make_url(\"/\")) as resp:\n                resp.content.set_exception(RuntimeError())\n                await resp.read()\n\n        assert session._connector is not None\n        assert len(session._connector._conns) == 0\n\n\nasync def test_release_resp_on_normal_exit_from_cm(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.ClientSession() as session:\n        async with session.get(server.make_url(\"/\")) as resp:\n            await resp.read()\n\n        assert session._connector is not None\n        assert len(session._connector._conns) == 1\n\n\nasync def test_non_close_detached_session_on_error_cm(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    session = aiohttp.ClientSession()\n    cm = session.get(server.make_url(\"/\"))\n    assert not session.closed\n    with pytest.raises(RuntimeError):\n        async with cm as resp:\n            resp.content.set_exception(RuntimeError())\n            await resp.read()\n    assert not session.closed\n\n\nasync def test_close_detached_session_on_non_existing_addr() -> None:\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            return []\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver())\n\n    session = aiohttp.ClientSession(connector=connector)\n\n    async with session:\n        cm = session.get(\"http://non-existing.example.com\")\n        assert not session.closed\n        with pytest.raises(Exception):\n            await cm\n\n    assert session.closed\n\n\nasync def test_aiohttp_request_context_manager(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.request(\"GET\", server.make_url(\"/\")) as resp:\n        await resp.read()\n        assert resp.status == 200\n\n\nasync def test_aiohttp_request_ctx_manager_close_sess_on_error(\n    ssl_ctx: ssl.SSLContext, aiohttp_server: AiohttpServer\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n\n    cm = aiohttp.request(\"GET\", server.make_url(\"/\"))\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        async with cm:\n            pass\n\n    assert cm._session.closed\n\n\nasync def test_aiohttp_request_ctx_manager_not_found() -> None:\n    with pytest.raises(aiohttp.ClientConnectionError):\n        async with aiohttp.request(\"GET\", \"http://wrong-dns-name.com\"):\n            assert False, \"never executed\"  # pragma: no cover\n\n\nasync def test_aiohttp_request_coroutine(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    not_an_awaitable = aiohttp.request(\"GET\", server.make_url(\"/\"))\n    with pytest.raises(\n        TypeError,\n        match=\"^object _SessionRequestContextManager \"\n        \"can't be used in 'await' expression$\",\n    ):\n        await not_an_awaitable  # type: ignore[misc]\n\n    await not_an_awaitable._coro  # coroutine 'ClientSession._request' was never awaited\n    await server.close()\n\n\nasync def test_yield_from_in_session_request(aiohttp_client: AiohttpClient) -> None:\n    # a test for backward compatibility with yield from syntax\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_close_context_manager(aiohttp_client: AiohttpClient) -> None:\n    # a test for backward compatibility with yield from syntax\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    ctx = client.get(\"/\")\n    ctx.close()\n    assert not ctx._coro.cr_running\n\n\nasync def test_session_auth(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n\n    r = await client.get(\"/\")\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"Authorization\"] == \"Basic bG9naW46cGFzcw==\"\n\n\nasync def test_session_auth_override(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n\n    r = await client.get(\"/\", auth=aiohttp.BasicAuth(\"other_login\", \"pass\"))\n    assert r.status == 200\n    content = await r.json()\n    val = content[\"headers\"][\"Authorization\"]\n    assert val == \"Basic b3RoZXJfbG9naW46cGFzcw==\"\n\n\nasync def test_session_auth_header_conflict(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n    headers = {\"Authorization\": \"Basic b3RoZXJfbG9naW46cGFzcw==\"}\n    with pytest.raises(ValueError):\n        await client.get(\"/\", headers=headers)\n\n\nasync def test_session_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, headers={\"X-Real-IP\": \"192.168.0.1\"})\n\n    r = await client.get(\"/\")\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"X-Real-IP\"] == \"192.168.0.1\"\n\n\nasync def test_session_headers_merge(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(\n        app, headers=[(\"X-Real-IP\", \"192.168.0.1\"), (\"X-Sent-By\", \"requests\")]\n    )\n\n    r = await client.get(\"/\", headers={\"X-Sent-By\": \"aiohttp\"})\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"X-Real-IP\"] == \"192.168.0.1\"\n    assert content[\"headers\"][\"X-Sent-By\"] == \"aiohttp\"\n\n\nasync def test_multidict_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert await request.read() == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    data = b\"sample data\"\n\n    async with client.post(\n        \"/\", data=data, headers=MultiDict({\"Content-Length\": str(len(data))})\n    ) as r:\n        assert r.status == 200\n\n\nasync def test_request_conn_closed(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.transport is not None\n        request.transport.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ServerDisconnectedError) as excinfo:\n        resp = await client.get(\"/\")\n        await resp.read()\n\n    assert str(excinfo.value) != \"\"\n\n\nasync def test_dont_close_explicit_connector(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    r = await client.get(\"/\")\n    await r.read()\n\n    assert client.session.connector is not None\n    assert 1 == len(client.session.connector._conns)\n\n\nasync def test_server_close_keepalive_connection() -> None:\n    loop = asyncio.get_event_loop()\n\n    class Proto(asyncio.Protocol):\n        def connection_made(self, transport: asyncio.BaseTransport) -> None:\n            assert isinstance(transport, asyncio.Transport)\n            self.transp: Optional[asyncio.Transport] = transport\n            self.data = b\"\"\n\n        def data_received(self, data: bytes) -> None:\n            self.data += data\n            assert data.endswith(b\"\\r\\n\\r\\n\")\n            assert self.transp is not None\n            self.transp.write(\n                b\"HTTP/1.1 200 OK\\r\\n\"\n                b\"CONTENT-LENGTH: 2\\r\\n\"\n                b\"CONNECTION: close\\r\\n\"\n                b\"\\r\\n\"\n                b\"ok\"\n            )\n            self.transp.close()\n\n        def connection_lost(self, exc: Optional[BaseException]) -> None:\n            self.transp = None\n\n    server = await loop.create_server(Proto, \"127.0.0.1\", unused_port())\n\n    addr = server.sockets[0].getsockname()\n\n    connector = aiohttp.TCPConnector(limit=1)\n    session = aiohttp.ClientSession(connector=connector)\n\n    url = \"http://{}:{}/\".format(*addr)\n    for i in range(2):\n        r = await session.request(\"GET\", url)\n        await r.read()\n        assert 0 == len(connector._conns)\n    await session.close()\n    await connector.close()\n    server.close()\n    await server.wait_closed()\n\n\nasync def test_handle_keepalive_on_closed_connection() -> None:\n    loop = asyncio.get_event_loop()\n\n    class Proto(asyncio.Protocol):\n        def connection_made(self, transport: asyncio.BaseTransport) -> None:\n            assert isinstance(transport, asyncio.Transport)\n            self.transp: Optional[asyncio.Transport] = transport\n            self.data = b\"\"\n\n        def data_received(self, data: bytes) -> None:\n            self.data += data\n            assert data.endswith(b\"\\r\\n\\r\\n\")\n            assert self.transp is not None\n            self.transp.write(b\"HTTP/1.1 200 OK\\r\\nCONTENT-LENGTH: 2\\r\\n\\r\\nok\")\n            self.transp.close()\n\n        def connection_lost(self, exc: Optional[BaseException]) -> None:\n            self.transp = None\n\n    server = await loop.create_server(Proto, \"127.0.0.1\", unused_port())\n\n    addr = server.sockets[0].getsockname()\n\n    async with aiohttp.TCPConnector(limit=1) as connector:\n        async with aiohttp.ClientSession(connector=connector) as session:\n            url = \"http://{}:{}/\".format(*addr)\n\n            r = await session.request(\"GET\", url)\n            await r.read()\n            assert 1 == len(connector._conns)\n            closed_conn = next(iter(connector._conns.values()))\n\n            await session.request(\"GET\", url)\n            assert 1 == len(connector._conns)\n            new_conn = next(iter(connector._conns.values()))\n            assert closed_conn is not new_conn\n\n    server.close()\n    await server.wait_closed()\n\n\nasync def test_error_in_performing_request(\n    ssl_ctx: ssl.SSLContext,\n    aiohttp_client: AiohttpClient,\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    def exception_handler(loop: object, context: object) -> None:\n        \"\"\"Skip log messages about destroyed but pending tasks\"\"\"\n\n    loop = asyncio.get_event_loop()\n    loop.set_exception_handler(exception_handler)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n\n    conn = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(server, connector=conn)\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"/\")\n\n    # second try should not hang\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"/\")\n\n\nasync def test_await_after_cancelling(aiohttp_client: AiohttpClient) -> None:\n    loop = asyncio.get_event_loop()\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    fut1 = loop.create_future()\n    fut2 = loop.create_future()\n\n    async def fetch1() -> None:\n        resp = await client.get(\"/\")\n        assert resp.status == 200\n        fut1.set_result(None)\n        with pytest.raises(asyncio.CancelledError):\n            await fut2\n        resp.release()\n\n    async def fetch2() -> None:\n        await fut1\n        resp = await client.get(\"/\")\n        assert resp.status == 200\n\n    async def canceller() -> None:\n        await fut1\n        fut2.cancel()\n\n    await asyncio.gather(fetch1(), fetch2(), canceller())\n\n\nasync def test_async_payload_generator(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        assert data == b\"1234567890\" * 100\n        return web.Response()\n\n    app = web.Application()\n    app.add_routes([web.post(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def gen() -> AsyncIterator[bytes]:\n        for i in range(100):\n            yield b\"1234567890\"\n\n    async with client.post(\"/\", data=gen()) as resp:\n        assert resp.status == 200\n\n\nasync def test_read_from_closed_response(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.read()\n\n\nasync def test_read_from_closed_response2(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n        await resp.read()\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.read()\n\n\nasync def test_read_from_closed_content(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.content.readline()\n\n\nasync def test_read_timeout(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(aiohttp.ServerTimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_socket_timeout(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(SocketTimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_read_timeout_closes_connection(aiohttp_client: AiohttpClient) -> None:\n    request_count = 0\n\n    async def handler(request: web.Request) -> web.Response:\n        nonlocal request_count\n        request_count += 1\n        if request_count < 3:\n            await asyncio.sleep(0.5)\n        return web.Response(body=f\"request:{request_count}\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(total=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n    # Make sure its really closed\n    assert client.session.connector is not None\n    assert not client.session.connector._conns\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n    # Make sure its really closed\n    assert not client.session.connector._conns\n    result = await client.get(\"/\")\n    assert await result.read() == b\"request:3\"\n\n    # Make sure its not closed\n    assert client.session.connector._conns\n\n\nasync def test_read_timeout_on_prepared_response(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(aiohttp.ServerTimeoutError):\n        async with await client.get(\"/\") as resp:\n            await resp.read()\n\n\nasync def test_timeout_with_full_buffer(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        \"\"\"Server response that never ends and always has more data available.\"\"\"\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n        while True:\n            await resp.write(b\"1\" * 1000)\n            await asyncio.sleep(0.01)\n\n    async def request(client: TestClient[web.Request]) -> None:\n        timeout = aiohttp.ClientTimeout(total=0.5)\n        async with await client.get(\"/\", timeout=timeout) as resp:\n            with pytest.raises(asyncio.TimeoutError):\n                async for data in resp.content.iter_chunked(1):\n                    await asyncio.sleep(0.01)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    # wait_for() used just to ensure that a failing test doesn't hang.\n    await asyncio.wait_for(request(client), 1)\n\n\nasync def test_read_bufsize_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1234567\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, read_bufsize=2)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.content.get_read_buffer_limits() == (2, 4)\n\n\nasync def test_read_bufsize_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1234567\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", read_bufsize=4) as resp:\n        assert resp.content.get_read_buffer_limits() == (4, 8)\n\n\nasync def test_http_empty_data_text(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        ret = \"ok\" if data == b\"\" else \"fail\"\n        resp = web.Response(text=ret)\n        resp.headers[\"Content-Type\"] = request.headers[\"Content-Type\"]\n        return resp\n\n    app = web.Application()\n    app.add_routes([web.post(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.post(\"/\", data=\"\") as resp:\n        assert resp.status == 200\n        assert await resp.text() == \"ok\"\n        assert resp.headers[\"Content-Type\"] == \"text/plain; charset=utf-8\"\n\n\nasync def test_max_field_size_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8190})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8190\n\n\nasync def test_max_field_size_session_default_fail(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_max_field_size_session_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, max_field_size=8191)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8191\n\n\nasync def test_max_field_size_request_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", max_field_size=8191) as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8191\n\n\nasync def test_max_line_size_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8190)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.reason == \"x\" * 8190\n\n\nasync def test_max_line_size_session_default_fail(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8192)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_max_line_size_session_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8191)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, max_line_size=8191)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.reason == \"x\" * 8191\n\n\nasync def test_max_line_size_request_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8191)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", max_line_size=8191) as resp:\n        assert resp.reason == \"x\" * 8191\n\n\n@pytest.mark.xfail(raises=asyncio.TimeoutError, reason=\"#7599\")\nasync def test_rejected_upload(\n    aiohttp_client: AiohttpClient, tmp_path: pathlib.Path\n) -> None:\n    async def ok_handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    async def not_ok_handler(request: web.Request) -> NoReturn:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/ok\", ok_handler)\n    app.router.add_post(\"/not_ok\", not_ok_handler)\n    client = await aiohttp_client(app)\n\n    file_size_bytes = 1024 * 1024\n    file_path = tmp_path / \"uploaded.txt\"\n    file_path.write_text(\"0\" * file_size_bytes, encoding=\"utf8\")\n\n    with open(file_path, \"rb\") as file:\n        data = {\"file\": file}\n        async with await client.post(\"/not_ok\", data=data) as resp_not_ok:\n            assert 400 == resp_not_ok.status\n\n    async with await client.get(\n        \"/ok\", timeout=aiohttp.ClientTimeout(total=0.01)\n    ) as resp_ok:\n        assert 200 == resp_ok.status\n\n\nasync def test_request_with_wrong_ssl_type(aiohttp_client: AiohttpClient) -> None:\n    app = web.Application()\n    session = await aiohttp_client(app)\n\n    with pytest.raises(TypeError, match=\"ssl should be SSLContext, Fingerprint, .*\"):\n        await session.get(\"/\", ssl=42)  # type: ignore[arg-type]\n\n\n@pytest.mark.parametrize(\n    (\"value\", \"exc_type\"),\n    [(42, TypeError), (\"InvalidUrl\", InvalidURL)],\n)\nasync def test_request_with_wrong_proxy(\n    aiohttp_client: AiohttpClient, value: Union[int, str], exc_type: Type[Exception]\n) -> None:\n    app = web.Application()\n    session = await aiohttp_client(app)\n\n    with pytest.raises(exc_type):\n        await session.get(\"/\", proxy=value)  # type: ignore[arg-type]\n\n\nasync def test_raise_for_status_is_none(aiohttp_client: AiohttpClient) -> None:\n    async def handler(_: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    session = await aiohttp_client(app, raise_for_status=None)\n\n    await session.get(\"/\")\n\n\n@pytest.mark.xfail(\n    reason=\"#8395 Error message regression for large headers in 3.9.4\",\n    raises=AssertionError,\n)\nasync def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n    \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n\n    async def handler(_: web.Request) -> web.Response:\n        return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n    ) as exc_info:\n        await client.get(\"/\")\n    assert exc_info.value.status == 400\n\n\nasync def test_exception_when_read_outside_of_session(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1\" * 1000000)\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    server = await aiohttp_server(app)\n    async with aiohttp.ClientSession() as sess:\n        resp = await sess.get(server.make_url(\"/\"))\n\n    with pytest.raises(RuntimeError, match=\"Connection closed\"):\n        await resp.read()\n",
            "new_file_content": "# HTTP client functional tests against aiohttp.web server\n\nimport asyncio\nimport datetime\nimport http.cookies\nimport io\nimport json\nimport pathlib\nimport socket\nimport ssl\nimport sys\nimport tarfile\nimport time\nimport zipfile\nfrom typing import (\n    Any,\n    AsyncIterator,\n    Awaitable,\n    Callable,\n    Dict,\n    List,\n    NoReturn,\n    Optional,\n    Type,\n    Union,\n)\nfrom unittest import mock\n\nimport pytest\nimport trustme\nfrom multidict import MultiDict\nfrom pytest_mock import MockerFixture\nfrom yarl import URL\n\nimport aiohttp\nfrom aiohttp import Fingerprint, ServerFingerprintMismatch, hdrs, web\nfrom aiohttp.abc import AbstractResolver, ResolveResult\nfrom aiohttp.client_exceptions import (\n    InvalidURL,\n    InvalidUrlClientError,\n    InvalidUrlRedirectClientError,\n    NonHttpUrlClientError,\n    NonHttpUrlRedirectClientError,\n    SocketTimeoutError,\n    TooManyRedirects,\n)\nfrom aiohttp.pytest_plugin import AiohttpClient, AiohttpServer\nfrom aiohttp.test_utils import TestClient, TestServer, unused_port\nfrom aiohttp.typedefs import Handler\n\n\n@pytest.fixture\ndef here() -> pathlib.Path:\n    return pathlib.Path(__file__).parent\n\n\n@pytest.fixture\ndef fname(here: pathlib.Path) -> pathlib.Path:\n    return here / \"conftest.py\"\n\n\nasync def test_keepalive_two_requests_success(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_keepalive_after_head_requests_success(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    app.router.add_route(\"HEAD\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.head(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert 1 == cnt_conn_reuse\n\n\n@pytest.mark.parametrize(\"status\", (101, 204, 304))\nasync def test_keepalive_after_empty_body_status(\n    aiohttp_client: AiohttpClient, status: int\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(status=status)\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert cnt_conn_reuse == 1\n\n\n@pytest.mark.parametrize(\"status\", (101, 204, 304))\nasync def test_keepalive_after_empty_body_status_stream_response(\n    aiohttp_client: AiohttpClient, status: int\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        stream_response = web.StreamResponse(status=status)\n        await stream_response.prepare(request)\n        return stream_response\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert cnt_conn_reuse == 1\n\n\nasync def test_keepalive_response_released(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    resp1.release()\n    resp2 = await client.get(\"/\")\n    resp2.release()\n\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_upgrade_connection_not_released_after_read(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(\n            status=101, headers={\"Connection\": \"Upgrade\", \"Upgrade\": \"tcp\"}\n        )\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    await resp.read()\n    assert resp.connection is not None\n    assert not resp.closed\n\n\nasync def test_keepalive_server_force_close_connection(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        response = web.Response(body=b\"OK\")\n        response.force_close()\n        return response\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    resp1.close()\n    resp2 = await client.get(\"/\")\n    resp2.close()\n\n    assert client._session.connector is not None\n    assert 0 == len(client._session.connector._conns)\n\n\nasync def test_keepalive_timeout_async_sleep() -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001)\n    await runner.setup()\n\n    port = unused_port()\n    site = web.TCPSite(runner, host=\"localhost\", port=port)\n    await site.start()\n\n    try:\n        async with aiohttp.ClientSession() as sess:\n            resp1 = await sess.get(f\"http://localhost:{port}/\")\n            await resp1.read()\n            # wait for server keepalive_timeout\n            await asyncio.sleep(0.01)\n            resp2 = await sess.get(f\"http://localhost:{port}/\")\n            await resp2.read()\n    finally:\n        await asyncio.gather(runner.shutdown(), site.stop())\n\n\n@pytest.mark.skipif(\n    sys.version_info[:2] == (3, 11),\n    reason=\"https://github.com/pytest-dev/pytest/issues/10763\",\n)\nasync def test_keepalive_timeout_sync_sleep() -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001)\n    await runner.setup()\n\n    port = unused_port()\n    site = web.TCPSite(runner, host=\"localhost\", port=port)\n    await site.start()\n\n    try:\n        async with aiohttp.ClientSession() as sess:\n            resp1 = await sess.get(f\"http://localhost:{port}/\")\n            await resp1.read()\n            # wait for server keepalive_timeout\n            # time.sleep is a more challenging scenario than asyncio.sleep\n            time.sleep(0.01)\n            resp2 = await sess.get(f\"http://localhost:{port}/\")\n            await resp2.read()\n    finally:\n        await asyncio.gather(runner.shutdown(), site.stop())\n\n\nasync def test_release_early(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        await request.read()\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n    resp = await client.get(\"/\")\n    assert resp.closed\n    await resp.wait_for_close()\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_HTTP_304(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(status=304)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    content = await resp.read()\n    assert content == b\"\"\n\n\nasync def test_stream_request_on_server_eof(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"OK\", status=200)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    app.add_routes([web.put(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def data_gen() -> AsyncIterator[bytes]:\n        for _ in range(2):\n            yield b\"just data\"\n            await asyncio.sleep(0.1)\n\n    assert client.session.connector is not None\n    async with client.put(\"/\", data=data_gen()) as resp:\n        assert 200 == resp.status\n        assert len(client.session.connector._acquired) == 1\n        conn = next(iter(client.session.connector._acquired))\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n    # Connection should have been reused\n    conns = next(iter(client.session.connector._conns.values()))\n    assert len(conns) == 1\n    assert conns[0][0] is conn\n\n\nasync def test_stream_request_on_server_eof_nested(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"OK\", status=200)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    app.add_routes([web.put(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def data_gen() -> AsyncIterator[bytes]:\n        for _ in range(2):\n            yield b\"just data\"\n            await asyncio.sleep(0.1)\n\n    async with client.put(\"/\", data=data_gen()) as resp:\n        assert 200 == resp.status\n        async with client.get(\"/\") as resp:\n            assert 200 == resp.status\n\n    # Should be 2 separate connections\n    assert client.session.connector is not None\n    conns = next(iter(client.session.connector._conns.values()))\n    assert len(conns) == 2\n\n\nasync def test_HTTP_304_WITH_BODY(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"test\", status=304)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    content = await resp.read()\n    assert content == b\"\"\n\n\nasync def test_auto_header_user_agent(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"aiohttp\" in request.headers[\"user-agent\"]\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_auto_headers_user_agent(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.USER_AGENT not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", skip_auto_headers=[\"user-agent\"]) as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_default_auto_headers_user_agent(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.USER_AGENT not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, skip_auto_headers=[\"user-agent\"])\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_auto_headers_content_type(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.CONTENT_TYPE not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", skip_auto_headers=[\"content-type\"]) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_bytesio(aiohttp_client: AiohttpClient) -> None:\n    data = b\"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert len(data) == request.content_length\n        val = await request.read()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(data) as file_handle:\n        async with client.post(\"/\", data=file_handle) as resp:\n            assert 200 == resp.status\n\n\nasync def test_post_data_with_bytesio_file(aiohttp_client: AiohttpClient) -> None:\n    data = b\"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        post_data = await request.post()\n        assert [\"file\"] == list(post_data.keys())\n        file_field = post_data[\"file\"]\n        assert isinstance(file_field, web.FileField)\n        assert data == file_field.file.read()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(data) as file_handle:\n        async with client.post(\"/\", data={\"file\": file_handle}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_post_data_stringio(aiohttp_client: AiohttpClient) -> None:\n    data = \"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert len(data) == request.content_length\n        assert request.headers[\"CONTENT-TYPE\"] == \"text/plain; charset=utf-8\"\n        val = await request.text()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data=io.StringIO(data)) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_textio_encoding(aiohttp_client: AiohttpClient) -> None:\n    data = \"текст\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.headers[\"CONTENT-TYPE\"] == \"text/plain; charset=koi8-r\"\n        val = await request.text()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    pl = aiohttp.TextIOPayload(io.StringIO(data), encoding=\"koi8-r\")\n    async with client.post(\"/\", data=pl) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_zipfile_filelike(aiohttp_client: AiohttpClient) -> None:\n    data = b\"This is a zip file payload text file.\"\n\n    async def handler(request: web.Request) -> web.Response:\n        val = await request.read()\n        assert data == val, \"Transmitted zipfile member failed to match original data.\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    buf = io.BytesIO()\n    with zipfile.ZipFile(file=buf, mode=\"w\") as zf:\n        with zf.open(\"payload1.txt\", mode=\"w\") as zip_filelike_writing:\n            zip_filelike_writing.write(data)\n\n    buf.seek(0)\n    zf = zipfile.ZipFile(file=buf, mode=\"r\")\n    resp = await client.post(\"/\", data=zf.open(\"payload1.txt\"))\n    assert 200 == resp.status\n\n\nasync def test_post_data_tarfile_filelike(aiohttp_client: AiohttpClient) -> None:\n    data = b\"This is a tar file payload text file.\"\n\n    async def handler(request: web.Request) -> web.Response:\n        val = await request.read()\n        assert data == val, \"Transmitted tarfile member failed to match original data.\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    buf = io.BytesIO()\n    with tarfile.open(fileobj=buf, mode=\"w\") as tf:\n        ti = tarfile.TarInfo(name=\"payload1.txt\")\n        ti.size = len(data)\n        tf.addfile(tarinfo=ti, fileobj=io.BytesIO(data))\n\n    # Random-access tarfile.\n    buf.seek(0)\n    tf = tarfile.open(fileobj=buf, mode=\"r:\")\n    resp = await client.post(\"/\", data=tf.extractfile(\"payload1.txt\"))\n    assert 200 == resp.status\n\n    # Streaming tarfile.\n    buf.seek(0)\n    tf = tarfile.open(fileobj=buf, mode=\"r|\")\n    for entry in tf:\n        resp = await client.post(\"/\", data=tf.extractfile(entry))\n        assert 200 == resp.status\n\n\nasync def test_ssl_client(\n    aiohttp_server: AiohttpServer,\n    ssl_ctx: ssl.SSLContext,\n    aiohttp_client: AiohttpClient,\n    client_ssl_ctx: ssl.SSLContext,\n) -> None:\n    connector = aiohttp.TCPConnector(ssl=client_ssl_ctx)\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"Test message\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"Test message\"\n\n\nasync def test_tcp_connector_fingerprint_ok(\n    aiohttp_server: AiohttpServer,\n    aiohttp_client: AiohttpClient,\n    ssl_ctx: ssl.SSLContext,\n    tls_certificate_fingerprint_sha256: bytes,\n) -> None:\n    tls_fingerprint = Fingerprint(tls_certificate_fingerprint_sha256)\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"Test message\")\n\n    connector = aiohttp.TCPConnector(ssl=tls_fingerprint)\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_tcp_connector_fingerprint_fail(\n    aiohttp_server: AiohttpServer,\n    aiohttp_client: AiohttpClient,\n    ssl_ctx: ssl.SSLContext,\n    tls_certificate_fingerprint_sha256: bytes,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    bad_fingerprint = b\"\\x00\" * len(tls_certificate_fingerprint_sha256)\n\n    connector = aiohttp.TCPConnector(ssl=Fingerprint(bad_fingerprint))\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    with pytest.raises(ServerFingerprintMismatch) as cm:\n        await client.get(\"/\")\n    exc = cm.value\n    assert exc.expected == bad_fingerprint\n    assert exc.got == tls_certificate_fingerprint_sha256\n\n\nasync def test_format_task_get(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app)\n    client = aiohttp.ClientSession()\n    task = asyncio.create_task(client.get(server.make_url(\"/\")))\n    assert f\"{task}\".startswith(\"<Task pending\")\n    resp = await task\n    resp.close()\n    await client.close()\n\n\nasync def test_str_params(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"q=t est\" in request.rel_url.query_string\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", params=\"q=t+est\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_drop_params_on_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok?a=redirect\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        assert request.rel_url.query_string == \"a=redirect\"\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\", params={\"a\": \"initial\"}) as resp:\n        assert resp.status == 200\n\n\nasync def test_drop_fragment_on_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok#fragment\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\") as resp:\n        assert resp.status == 200\n        assert resp.url.path == \"/ok\"\n\n\nasync def test_drop_fragment(aiohttp_client: AiohttpClient) -> None:\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/ok#fragment\") as resp:\n        assert resp.status == 200\n        assert resp.url.path == \"/ok\"\n\n\nasync def test_history(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/ok\") as resp:\n        assert len(resp.history) == 0\n        assert resp.status == 200\n\n    async with client.get(\"/redirect\") as resp_redirect:\n        assert len(resp_redirect.history) == 1\n        assert resp_redirect.history[0].status == 301\n        assert resp_redirect.status == 200\n\n\nasync def test_keepalive_closed_by_server(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        resp = web.Response(body=b\"OK\")\n        resp.force_close()\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    val1 = await resp1.read()\n    assert val1 == b\"OK\"\n    resp2 = await client.get(\"/\")\n    val2 = await resp2.read()\n    assert val2 == b\"OK\"\n\n    assert client._session.connector is not None\n    assert 0 == len(client._session.connector._conns)\n\n\nasync def test_wait_for(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await asyncio.wait_for(client.get(\"/\"), 10)\n    assert resp.status == 200\n    txt = await resp.text()\n    assert txt == \"OK\"\n\n\nasync def test_raw_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n        raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers)\n        assert raw_headers == (\n            (b\"Content-Length\", b\"0\"),\n            (b\"Date\", mock.ANY),\n            (b\"Server\", mock.ANY),\n        )\n\n\nasync def test_host_header_first(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert list(request.headers)[0] == hdrs.HOST\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_empty_header_values(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response()\n        resp.headers[\"X-Empty\"] = \"\"\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n        raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers)\n        assert raw_headers == (\n            (b\"X-Empty\", b\"\"),\n            (b\"Content-Length\", b\"0\"),\n            (b\"Date\", mock.ANY),\n            (b\"Server\", mock.ANY),\n        )\n\n\nasync def test_204_with_gzipped_content_encoding(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=204)\n        resp.content_length = 0\n        resp.content_type = \"application/json\"\n        # resp.enable_compression(web.ContentCoding.gzip)\n        resp.headers[\"Content-Encoding\"] = \"gzip\"\n        await resp.prepare(request)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"DELETE\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.delete(\"/\") as resp:\n        assert resp.status == 204\n        assert resp.closed\n\n\nasync def test_timeout_on_reading_headers(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\", timeout=aiohttp.ClientTimeout(total=0.01))\n\n\nasync def test_timeout_on_conn_reading_headers(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    # tests case where user did not set a connection timeout\n\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    conn = aiohttp.TCPConnector()\n    client = await aiohttp_client(app, connector=conn)\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\", timeout=aiohttp.ClientTimeout(total=0.01))\n\n\nasync def test_timeout_on_session_read_timeout(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    conn = aiohttp.TCPConnector()\n    client = await aiohttp_client(\n        app, connector=conn, timeout=aiohttp.ClientTimeout(sock_read=0.01)\n    )\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_read_timeout_between_chunks(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        # write data 4 times, with pauses. Total time 2 seconds.\n        for _ in range(4):\n            await asyncio.sleep(0.5)\n            await resp.write(b\"data\\n\")\n        return resp\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    # A timeout of 0.2 seconds should apply per read.\n    timeout = aiohttp.ClientTimeout(sock_read=1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    res = b\"\"\n    async with await client.get(\"/\") as resp:\n        res += await resp.read()\n\n    assert res == b\"data\\n\" * 4\n\n\nasync def test_read_timeout_on_reading_chunks(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        await resp.write(b\"data\\n\")\n        await asyncio.sleep(1)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    # A timeout of 0.2 seconds should apply per read.\n    timeout = aiohttp.ClientTimeout(sock_read=0.2)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    async with await client.get(\"/\") as resp:\n        assert (await resp.content.read(5)) == b\"data\\n\"\n        with pytest.raises(asyncio.TimeoutError):\n            await resp.content.read()\n\n\nasync def test_read_timeout_on_write(aiohttp_client: AiohttpClient) -> None:\n    async def gen_payload() -> AsyncIterator[bytes]:\n        # Delay writing to ensure read timeout isn't triggered before writing completes.\n        await asyncio.sleep(0.5)\n        yield b\"foo\"\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=await request.read())\n\n    app = web.Application()\n    app.router.add_put(\"/\", handler)\n\n    timeout = aiohttp.ClientTimeout(total=None, sock_read=0.1)\n    client = await aiohttp_client(app)\n    async with client.put(\"/\", data=gen_payload(), timeout=timeout) as resp:\n        result = await resp.read()  # Should not trigger a read timeout.\n    assert result == b\"foo\"\n\n\nasync def test_timeout_on_reading_data(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    loop = asyncio.get_event_loop()\n\n    fut = loop.create_future()\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        fut.set_result(None)\n        await asyncio.sleep(0.2)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", timeout=aiohttp.ClientTimeout(1))\n    await fut\n\n    with pytest.raises(asyncio.TimeoutError):\n        await resp.read()\n\n\nasync def test_timeout_none(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", timeout=None) as resp:\n        assert resp.status == 200\n\n\nasync def test_readline_error_on_conn_close(aiohttp_client: AiohttpClient) -> None:\n    loop = asyncio.get_event_loop()\n\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n\n        # make sure connection is closed by client.\n        with pytest.raises(aiohttp.ServerDisconnectedError):\n            for _ in range(10):\n                await resp.write(b\"data\\n\")\n                await asyncio.sleep(0.5)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        timer_started = False\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        with pytest.raises(aiohttp.ClientConnectionError):\n            while True:\n                data = await resp.content.readline()\n                data = data.strip()\n                assert data\n                assert data == b\"data\"\n                if not timer_started:\n                    loop.call_later(1.0, resp.release)\n                    timer_started = True\n    finally:\n        await session.close()\n\n\nasync def test_no_error_on_conn_close_if_eof(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp_ = web.StreamResponse()\n        await resp_.prepare(request)\n        await resp_.write(b\"data\\n\")\n        await asyncio.sleep(0.5)\n        return resp_\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        while True:\n            data = await resp.content.readline()\n            data = data.strip()\n            if not data:\n                break\n            assert data == b\"data\"\n\n        assert resp.content.exception() is None\n    finally:\n        await session.close()\n\n\nasync def test_error_not_overwrote_on_conn_close(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp_ = web.StreamResponse()\n        await resp_.prepare(request)\n        return resp_\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        resp.content.set_exception(ValueError())\n    finally:\n        await session.close()\n\n    assert isinstance(resp.content.exception(), ValueError)\n\n\nasync def test_HTTP_200_OK_METHOD(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n\n    client = await aiohttp_client(app)\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        resp = await client.request(meth, \"/\")\n        assert resp.status == 200\n        assert len(resp.history) == 0\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_HTTP_200_OK_METHOD_connector(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    conn = aiohttp.TCPConnector()\n    conn.clear_dns_cache()\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n    client = await aiohttp_client(app, connector=conn)\n\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\"):\n        resp = await client.request(meth, \"/\")\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        assert resp.status == 200\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_HTTP_302_REDIRECT_GET(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\") as resp:\n        assert 200 == resp.status\n        assert 1 == len(resp.history)\n\n\nasync def test_HTTP_302_REDIRECT_HEAD(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n    app.router.add_head(\"/\", handler)\n    app.router.add_head(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    async with client.request(\"head\", \"/redirect\") as resp:\n        assert 200 == resp.status\n        assert 1 == len(resp.history)\n        assert resp.method == \"HEAD\"\n\n\nasync def test_HTTP_302_REDIRECT_NON_HTTP(aiohttp_client: AiohttpClient) -> None:\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"ftp://127.0.0.1/test/\")\n\n    app = web.Application()\n    app.router.add_get(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(NonHttpUrlRedirectClientError):\n        await client.get(\"/redirect\")\n\n\nasync def test_HTTP_302_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\")\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"GET\"\n    resp.close()\n\n\nasync def test_HTTP_302_REDIRECT_POST_with_content_length_hdr(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPFound(location=\"/\")\n\n    data = json.dumps({\"some\": \"data\"})\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\n        \"/redirect\", data=data, headers={\"Content-Length\": str(len(data))}\n    )\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"GET\"\n    resp.close()\n\n\nasync def test_HTTP_307_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPTemporaryRedirect(location=\"/\")\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"POST\"\n    resp.close()\n\n\nasync def test_HTTP_308_PERMANENT_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPPermanentRedirect(location=\"/\")\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"POST\"\n    resp.close()\n\n\nasync def test_HTTP_302_max_redirects(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    async def redirect(request: web.Request) -> NoReturn:\n        count = int(request.match_info[\"count\"])\n        assert count\n        raise web.HTTPFound(location=f\"/redirect/{count - 1}\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(r\"/redirect/{count:\\d+}\", redirect)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(TooManyRedirects) as ctx:\n        await client.get(\"/redirect/5\", max_redirects=2)\n    assert 2 == len(ctx.value.history)\n    assert ctx.value.request_info.url.path == \"/redirect/5\"\n    assert ctx.value.request_info.method == \"GET\"\n\n\nasync def test_HTTP_200_GET_WITH_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", params={\"q\": \"test\"})\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"q=test\"\n    resp.close()\n\n\nasync def test_HTTP_200_GET_WITH_MultiDict_PARAMS(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", params=MultiDict([(\"q\", \"test\"), (\"q\", \"test2\")]))\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"q=test&q=test2\"\n    resp.close()\n\n\nasync def test_HTTP_200_GET_WITH_MIXED_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/?test=true\", params={\"q\": \"test\"})\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"test=true&q=test\"\n    resp.close()\n\n\nasync def test_POST_DATA(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n\nasync def test_POST_DATA_with_explicit_formdata(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"text\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"name\": \"text\"}\n    resp.close()\n\n\nasync def test_POST_DATA_with_charset(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        mp = await request.multipart()\n        part = await mp.next()\n        assert isinstance(part, aiohttp.BodyPartReader)\n        text = await part.text()\n        return web.Response(text=text)\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"текст\", content_type=\"text/plain; charset=koi8-r\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_DATA_formdats_with_charset(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        mp = await request.post()\n        assert \"name\" in mp\n        assert isinstance(mp[\"name\"], str)\n        return web.Response(text=mp[\"name\"])\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData(charset=\"koi8-r\")\n    form.add_field(\"name\", \"текст\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_DATA_with_charset_post(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"name\"], str)\n        return web.Response(text=data[\"name\"])\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"текст\", content_type=\"text/plain; charset=koi8-r\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_MultiDict(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data == MultiDict([(\"q\", \"test1\"), (\"q\", \"test2\")])\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\n        \"/\", data=MultiDict([(\"q\", \"test1\"), (\"q\", \"test2\")])\n    ) as resp:\n        assert 200 == resp.status\n\n\nasync def test_POST_DATA_DEFLATE(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    # True is not a valid type, but still tested for backwards compatibility.\n    resp = await client.post(\"/\", data={\"some\": \"data\"}, compress=True)  # type: ignore[arg-type]\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n\nasync def test_POST_FILES(aiohttp_client: AiohttpClient, fname: pathlib.Path) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            content1 = f.read()\n        content2 = data[\"some\"].file.read()\n        assert content1 == content2\n        assert isinstance(data[\"test\"], web.FileField)\n        assert data[\"test\"].file.read() == b\"data\"\n        assert isinstance(data[\"some\"], web.FileField)\n        data[\"some\"].file.close()\n        data[\"test\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data={\"some\": f, \"test\": io.BytesIO(b\"data\")}, chunked=True\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_DEFLATE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            content1 = f.read()\n        content2 = data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        assert content1 == content2\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data={\"some\": f}, chunked=True, compress=\"deflate\"\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_bytes(aiohttp_client: AiohttpClient) -> None:\n    body = b\"0\" * 12345\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        assert body == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data=body) as resp:\n        assert 200 == resp.status\n\n\nasync def test_POST_bytes_too_large(aiohttp_client: AiohttpClient) -> None:\n    body = b\"0\" * (2**20 + 1)\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.content.read()\n        assert body == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.warns(ResourceWarning):\n        resp = await client.post(\"/\", data=body)\n\n    assert 200 == resp.status\n    resp.close()\n\n\nasync def test_POST_FILES_STR(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        with fname.open(\"rb\") as f:\n            content1 = f.read().decode()\n        content2 = data[\"some\"]\n        assert content1 == content2\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data={\"some\": f.read().decode()}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_STR_SIMPLE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f.read()) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_LIST(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert fname.name == data[\"some\"].filename\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=[(\"some\", f)]) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_CT(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert fname.name == data[\"some\"].filename\n        assert \"text/plain\" == data[\"some\"].content_type\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        form = aiohttp.FormData()\n        form.add_field(\"some\", f, content_type=\"text/plain\")\n        async with client.post(\"/\", data=form) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.text()\n        with fname.open(\"rb\") as f:\n            content = f.read().decode()\n            assert content == data\n        # if system cannot determine 'text/x-python' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"text/plain\",\n            \"application/octet-stream\",\n            \"text/x-python\",\n        ]\n        assert \"content-disposition\" not in request.headers\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE_content_disposition(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.text()\n        with fname.open(\"rb\") as f:\n            content = f.read().decode()\n            assert content == data\n        # if system cannot determine 'application/pgp-keys' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"text/plain\",\n            \"application/octet-stream\",\n            \"text/x-python\",\n        ]\n        assert request.headers[\"content-disposition\"] == (\n            'inline; filename=\"conftest.py\"'\n        )\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data=aiohttp.get_payload(f, disposition=\"inline\")\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE_BINARY(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data\n        # if system cannot determine 'application/pgp-keys' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"application/pgp-keys\",\n            \"text/plain\",\n            \"text/x-python\",\n            \"application/octet-stream\",\n        ]\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_IO(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"unknown\"], web.FileField)\n        assert b\"data\" == data[\"unknown\"].file.read()\n        assert data[\"unknown\"].content_type == \"application/octet-stream\"\n        assert data[\"unknown\"].filename == \"unknown\"\n        data[\"unknown\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(b\"data\") as file_handle:\n        async with client.post(\"/\", data=[file_handle]) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_IO_WITH_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data[\"test\"] == \"true\"\n        assert isinstance(data[\"unknown\"], web.FileField)\n        assert data[\"unknown\"].content_type == \"application/octet-stream\"\n        assert data[\"unknown\"].filename == \"unknown\"\n        assert data[\"unknown\"].file.read() == b\"data\"\n        data[\"unknown\"].file.close()\n        assert data.getall(\"q\") == [\"t1\", \"t2\"]\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(b\"data\") as file_handle:\n        async with client.post(\n            \"/\",\n            data=((\"test\", \"true\"), MultiDict([(\"q\", \"t1\"), (\"q\", \"t2\")]), file_handle),\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_WITH_DATA(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data[\"test\"] == \"true\"\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].content_type in [\n            \"text/x-python\",\n            \"text/plain\",\n            \"application/octet-stream\",\n        ]\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            assert data[\"some\"].file.read() == f.read()\n            data[\"some\"].file.close()\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data={\"test\": \"true\", \"some\": f}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_STREAM_DATA(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/octet-stream\"\n        content = await request.read()\n        with fname.open(\"rb\") as f:\n            expected = f.read()\n            assert request.content_length == len(expected)\n            assert content == expected\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        data_size = len(f.read())\n\n    async def gen(fname: pathlib.Path) -> AsyncIterator[bytes]:\n        with fname.open(\"rb\") as f:\n            data = f.read(100)\n            while data:\n                yield data\n                data = f.read(100)\n\n    async with client.post(\n        \"/\", data=gen(fname), headers={\"Content-Length\": str(data_size)}\n    ) as resp:\n        assert 200 == resp.status\n\n\nasync def test_json(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/json\"\n        data = await request.json()\n        return web.Response(body=aiohttp.JsonPayload(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/\", json={\"some\": \"data\"})\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n    with pytest.raises(ValueError):\n        await client.post(\"/\", data=\"some data\", json={\"some\": \"data\"})\n\n\nasync def test_json_custom(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/json\"\n        data = await request.json()\n        return web.Response(body=aiohttp.JsonPayload(data))\n\n    used = False\n\n    def dumps(obj: Any) -> str:\n        nonlocal used\n        used = True\n        return json.dumps(obj)\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app, json_serialize=dumps)\n\n    resp = await client.post(\"/\", json={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert used\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n    with pytest.raises(ValueError):\n        await client.post(\"/\", data=\"some data\", json={\"some\": \"data\"})\n\n\nasync def test_expect_continue(aiohttp_client: AiohttpClient) -> None:\n    expect_called = False\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data == {\"some\": \"data\"}\n        return web.Response()\n\n    async def expect_handler(request: web.Request) -> None:\n        nonlocal expect_called\n        expect = request.headers[hdrs.EXPECT]\n        assert expect.lower() == \"100-continue\"\n        assert request.transport is not None\n        request.transport.write(b\"HTTP/1.1 100 Continue\\r\\n\\r\\n\")\n        expect_called = True\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler, expect_handler=expect_handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data={\"some\": \"data\"}, expect100=True) as resp:\n        assert 200 == resp.status\n    assert expect_called\n\n\nasync def test_encoding_deflate(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        resp.enable_compression(web.ContentCoding.deflate)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_deflate_nochunk(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_compression(web.ContentCoding.deflate)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_gzip(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        resp.enable_compression(web.ContentCoding.gzip)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_gzip_write_by_chunks(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        resp.enable_compression(web.ContentCoding.gzip)\n        await resp.prepare(request)\n        await resp.write(b\"0\")\n        await resp.write(b\"0\")\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"00\"\n    resp.close()\n\n\nasync def test_encoding_gzip_nochunk(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_compression(web.ContentCoding.gzip)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_bad_payload_compression(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.headers[\"Content-Encoding\"] = \"gzip\"\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_bad_payload_chunked_encoding(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        resp.force_close()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write(b\"9\\r\\n\\r\\n\")\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_no_payload_304_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test a 304 response with no payload with chunked set should have it removed.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=304)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING not in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_head_request_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test a head response with chunked set should have it removed.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=200)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_head(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.head(\"/\")\n    assert resp.status == 200\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING not in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_no_payload_200_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test chunked is preserved on a 200 response with no payload.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=200)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 200\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_bad_payload_content_length(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.headers[\"Content-Length\"] = \"10000\"\n        resp.force_close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_payload_content_length_by_chunks(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"2\"})\n        await resp.prepare(request)\n        await resp.write(b\"answer\")\n        await resp.write(b\"two\")\n        assert request.transport is not None\n        request.transport.close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    data = await resp.read()\n    assert data == b\"an\"\n    resp.close()\n\n\nasync def test_chunked(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    assert resp.headers[\"Transfer-Encoding\"] == \"chunked\"\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_shortcuts(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n    client = await aiohttp_client(app)\n\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        coro = getattr(client.session, meth)\n        resp = await coro(client.make_url(\"/\"))\n\n        assert resp.status == 200\n        assert len(resp.history) == 0\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_cookies(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test1\", \"test3\"}\n        assert request.cookies[\"test1\"] == \"123\"\n        assert request.cookies[\"test3\"] == \"456\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test1\": \"123\", \"test2\": c})\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_per_request(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test1\", \"test3\", \"test4\", \"test6\"}\n        assert request.cookies[\"test1\"] == \"123\"\n        assert request.cookies[\"test3\"] == \"456\"\n        assert request.cookies[\"test4\"] == \"789\"\n        assert request.cookies[\"test6\"] == \"abc\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test1\": \"123\", \"test2\": c})\n\n    rc: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    rc.set(\"test6\", \"abc\", \"abc\")\n\n    cookies: Dict[str, Union[str, \"http.cookies.Morsel[str]\"]]\n    cookies = {\"test4\": \"789\", \"test5\": rc}\n    async with client.get(\"/\", cookies=cookies) as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def redirect1(request: web.Request) -> web.Response:\n        ret = web.Response(status=301, headers={\"Location\": \"/redirect2\"})\n        ret.set_cookie(\"c\", \"1\")\n        return ret\n\n    async def redirect2(request: web.Request) -> web.Response:\n        ret = web.Response(status=301, headers={\"Location\": \"/\"})\n        ret.set_cookie(\"c\", \"2\")\n        return ret\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"c\"}\n        assert request.cookies[\"c\"] == \"2\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/redirect1\", redirect1)\n    app.router.add_get(\"/redirect2\", redirect2)\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/redirect1\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_on_empty_session_jar(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"custom-cookie\" in request.cookies\n        assert request.cookies[\"custom-cookie\"] == \"abc\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies=None)\n\n    async with client.get(\"/\", cookies={\"custom-cookie\": \"abc\"}) as resp:\n        assert 200 == resp.status\n\n\nasync def test_morsel_with_attributes(aiohttp_client: AiohttpClient) -> None:\n    # A comment from original test:\n    #\n    # No cookie attribute should pass here\n    # they are only used as filters\n    # whether to send particular cookie or not.\n    # E.g. if cookie expires it just becomes thrown away.\n    # Server who sent the cookie with some attributes\n    # already knows them, no need to send this back again and again\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test3\"}\n        assert request.cookies[\"test3\"] == \"456\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n    c[\"httponly\"] = True\n    c[\"secure\"] = True\n    c[\"max-age\"] = 1000\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test2\": c})\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_set_cookies(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"ISAWPLB{A7F52349-3531-4DA9-8776-F74BC6F4F1BB}=\"\n            \"{925EC0B8-CB17-4BEB-8A35-1033813B0523}; \"\n            \"HttpOnly; Path=/\",\n        )\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with mock.patch(\"aiohttp.client_reqrep.client_logger\") as m_log:\n        async with client.get(\"/\") as resp:\n            assert 200 == resp.status\n            cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\"}\n\n        m_log.warning.assert_called_with(\"Can not load response cookies: %s\", mock.ANY)\n\n\nasync def test_set_cookies_expired(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"c3=cookie3; HttpOnly; Path=/ Expires=Tue, 1 Jan 1980 12:00:00 GMT; \",\n        )\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        cookie_names = {c.key for c in client.session.cookie_jar}\n    assert cookie_names == {\"c1\", \"c2\"}\n\n\nasync def test_set_cookies_max_age(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\"Set-Cookie\", \"c3=cookie3; HttpOnly; Path=/ Max-Age=1; \")\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\", \"c3\"}\n        await asyncio.sleep(2)\n        cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\"}\n\n\nasync def test_set_cookies_max_age_overflow(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"overflow=overflow; HttpOnly; Path=/ Max-Age=\" + str(overflow) + \"; \",\n        )\n        return ret\n\n    overflow = int(\n        datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()\n    )\n    empty = None\n    try:\n        empty = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(\n            seconds=overflow\n        )\n    except OverflowError as ex:\n        assert isinstance(ex, OverflowError)\n    assert not isinstance(empty, datetime.datetime)\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        for cookie in client.session.cookie_jar:\n            assert cookie.key == \"overflow\"\n            assert int(cookie[\"max-age\"]) == int(overflow)\n\n\nasync def test_request_conn_error() -> None:\n    client = aiohttp.ClientSession()\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"http://0.0.0.0:1\")\n    await client.close()\n\n\n@pytest.mark.xfail\nasync def test_broken_connection(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.transport is not None\n        request.transport.close()\n        return web.Response(text=\"answer\" * 1000)\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_broken_connection_2(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"1000\"})\n        await resp.prepare(request)\n        await resp.write(b\"answer\")\n        assert request.transport is not None\n        request.transport.close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n    resp.close()\n\n\nasync def test_custom_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.headers[\"x-api-key\"] == \"foo\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\n        \"/\", headers={\"Content-Type\": \"application/json\", \"x-api-key\": \"foo\"}\n    ) as resp:\n        assert resp.status == 200\n\n\nasync def test_redirect_to_absolute_url(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=client.make_url(\"/\"))\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/redirect\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_redirect_without_location_header(aiohttp_client: AiohttpClient) -> None:\n    body = b\"redirect\"\n\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, body=body)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/redirect\")\n    data = await resp.read()\n    assert data == body\n\n\nINVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW = (\n    # yarl.URL.__new__ raises ValueError\n    (\"http://:/\", \"http://:/\"),\n    (\"http://example.org:non_int_port/\", \"http://example.org:non_int_port/\"),\n)\n\nINVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN = (\n    # # yarl.URL.origin raises ValueError\n    (\"http:/\", \"http:///\"),\n    (\"http:/example.com\", \"http:///example.com\"),\n    (\"http:///example.com\", \"http:///example.com\"),\n)\n\nNON_HTTP_URL_WITH_ERROR_MESSAGE = (\n    (\"call:+380123456789\", r\"call:\\+380123456789\"),\n    (\"skype:handle\", \"skype:handle\"),\n    (\"slack://instance/room\", \"slack://instance/room\"),\n    (\"steam:code\", \"steam:code\"),\n    (\"twitter://handle\", \"twitter://handle\"),\n    (\"bluesky://profile/d:i:d\", \"bluesky://profile/d:i:d\"),\n)\n\n\n@pytest.mark.parametrize(\n    (\"url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, InvalidUrlClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n        ),\n        *(\n            (url, message, NonHttpUrlClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_and_non_http_url(\n    url: str, error_message_url: str, expected_exception_class: Type[Exception]\n) -> None:\n    async with aiohttp.ClientSession() as http_session:\n        with pytest.raises(\n            expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n        ):\n            await http_session.get(url)\n\n\n@pytest.mark.parametrize(\n    (\"invalid_redirect_url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlRedirectClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n            + INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, NonHttpUrlRedirectClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_redirect_url(\n    aiohttp_client: AiohttpClient,\n    invalid_redirect_url: str,\n    error_message_url: str,\n    expected_exception_class: Type[Exception],\n) -> None:\n    headers = {hdrs.LOCATION: invalid_redirect_url}\n\n    async def generate_redirecting_response(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers=headers)\n\n    app = web.Application()\n    app.router.add_get(\"/redirect\", generate_redirecting_response)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n    ):\n        await client.get(\"/redirect\")\n\n\n@pytest.mark.parametrize(\n    (\"invalid_redirect_url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlRedirectClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n            + INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, NonHttpUrlRedirectClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_redirect_url_multiple_redirects(\n    aiohttp_client: AiohttpClient,\n    invalid_redirect_url: str,\n    error_message_url: str,\n    expected_exception_class: Type[Exception],\n) -> None:\n    app = web.Application()\n\n    for path, location in [\n        (\"/redirect\", \"/redirect1\"),\n        (\"/redirect1\", \"/redirect2\"),\n        (\"/redirect2\", invalid_redirect_url),\n    ]:\n\n        async def generate_redirecting_response(request: web.Request) -> web.Response:\n            return web.Response(status=301, headers={hdrs.LOCATION: location})\n\n        app.router.add_get(path, generate_redirecting_response)\n\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n    ):\n        await client.get(\"/redirect\")\n\n\n@pytest.mark.parametrize(\n    (\"status\", \"expected_ok\"),\n    (\n        (200, True),\n        (201, True),\n        (301, True),\n        (400, False),\n        (403, False),\n        (500, False),\n    ),\n)\nasync def test_ok_from_status(\n    aiohttp_client: AiohttpClient, status: int, expected_ok: bool\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=status, body=b\"\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/endpoint\", handler)\n    client = await aiohttp_client(app, raise_for_status=False)\n    async with client.get(\"/endpoint\") as resp:\n        assert resp.ok is expected_ok\n\n\nasync def test_raise_for_status(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, raise_for_status=True)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_raise_for_status_per_request(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\", raise_for_status=True)\n\n\nasync def test_raise_for_status_disable_per_request(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, raise_for_status=True)\n\n    async with client.get(\"/\", raise_for_status=False) as resp:\n        assert 400 == resp.status\n\n\nasync def test_request_raise_for_status_default(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.request(\"GET\", server.make_url(\"/\")) as resp:\n        assert resp.status == 400\n\n\nasync def test_request_raise_for_status_disabled(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n    url = server.make_url(\"/\")\n\n    async with aiohttp.request(\"GET\", url, raise_for_status=False) as resp:\n        assert resp.status == 400\n\n\nasync def test_request_raise_for_status_enabled(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n    url = server.make_url(\"/\")\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        async with aiohttp.request(\"GET\", url, raise_for_status=True):\n            assert False, \"never executed\"  # pragma: no cover\n\n\nasync def test_session_raise_for_status_coro(aiohttp_client: AiohttpClient) -> None:\n    async def handle(request: web.Request) -> web.Response:\n        return web.Response(text=\"ok\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handle)\n\n    raise_for_status_called = 0\n\n    async def custom_r4s(response: aiohttp.ClientResponse) -> None:\n        nonlocal raise_for_status_called\n        raise_for_status_called += 1\n        assert response.status == 200\n        assert response.request_info.method == \"GET\"\n\n    client = await aiohttp_client(app, raise_for_status=custom_r4s)\n    await client.get(\"/\")\n    assert raise_for_status_called == 1\n    await client.get(\"/\", raise_for_status=True)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n    await client.get(\"/\", raise_for_status=False)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n\n\nasync def test_request_raise_for_status_coro(aiohttp_client: AiohttpClient) -> None:\n    async def handle(request: web.Request) -> web.Response:\n        return web.Response(text=\"ok\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handle)\n\n    raise_for_status_called = 0\n\n    async def custom_r4s(response: aiohttp.ClientResponse) -> None:\n        nonlocal raise_for_status_called\n        raise_for_status_called += 1\n        assert response.status == 200\n        assert response.request_info.method == \"GET\"\n\n    client = await aiohttp_client(app)\n    await client.get(\"/\", raise_for_status=custom_r4s)\n    assert raise_for_status_called == 1\n    await client.get(\"/\", raise_for_status=True)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n    await client.get(\"/\", raise_for_status=False)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n\n\nasync def test_invalid_idna() -> None:\n    session = aiohttp.ClientSession()\n    try:\n        with pytest.raises(aiohttp.InvalidURL):\n            await session.get(\"http://\\u2061owhefopw.com\")\n    finally:\n        await session.close()\n\n\nasync def test_creds_in_auth_and_url() -> None:\n    session = aiohttp.ClientSession()\n    try:\n        with pytest.raises(ValueError):\n            await session.get(\n                \"http://user:pass@example.com\", auth=aiohttp.BasicAuth(\"user2\", \"pass2\")\n            )\n    finally:\n        await session.close()\n\n\n@pytest.fixture\ndef create_server_for_url_and_handler(\n    aiohttp_server: AiohttpServer, tls_certificate_authority: trustme.CA\n) -> Callable[[URL, Handler], Awaitable[TestServer]]:\n    def create(url: URL, srv: Handler) -> Awaitable[TestServer]:\n        app = web.Application()\n        app.router.add_route(\"GET\", url.path, srv)\n\n        if url.scheme == \"https\":\n            assert url.host\n            cert = tls_certificate_authority.issue_cert(\n                url.host, \"localhost\", \"127.0.0.1\"\n            )\n            ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n            cert.configure_cert(ssl_ctx)\n            return aiohttp_server(app, ssl=ssl_ctx)\n        return aiohttp_server(app)\n\n    return create\n\n\n@pytest.mark.parametrize(\n    [\"url_from_s\", \"url_to_s\", \"is_drop_header_expected\"],\n    [\n        [\n            \"http://host1.com/path1\",\n            \"http://host2.com/path2\",\n            True,\n        ],\n        [\"http://host1.com/path1\", \"https://host1.com/path1\", False],\n        [\"https://host1.com/path1\", \"http://host1.com/path2\", True],\n    ],\n    ids=(\n        \"entirely different hosts\",\n        \"http -> https\",\n        \"https -> http\",\n    ),\n)\nasync def test_drop_auth_on_redirect_to_other_host(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n    url_from_s: str,\n    url_to_s: str,\n    is_drop_header_expected: bool,\n) -> None:\n    url_from, url_to = URL(url_from_s), URL(url_to_s)\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        if is_drop_header_expected:\n            assert \"Authorization\" not in request.headers, \"Header wasn't dropped\"\n        else:\n            assert \"Authorization\" in request.headers, \"Header was dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(connector=connector) as client:\n        resp = await client.get(\n            url_from,\n            auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n        )\n        assert resp.status == 200\n        resp = await client.get(\n            url_from,\n            headers={\"Authorization\": \"Basic dXNlcjpwYXNz\"},\n        )\n        assert resp.status == 200\n\n\nasync def test_auth_persist_on_redirect_to_other_host_with_global_auth(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n) -> None:\n    url_from = URL(\"http://host1.com/path1\")\n    url_to = URL(\"http://host2.com/path2\")\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        assert \"Authorization\" in request.headers, \"Header was dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(\n        connector=connector, auth=aiohttp.BasicAuth(\"user\", \"pass\")\n    ) as client:\n        resp = await client.get(url_from)\n        assert resp.status == 200\n\n\nasync def test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n) -> None:\n    url_from = URL(\"http://host1.com/path1\")\n    url_to = URL(\"http://host2.com/path2\")\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        assert \"Authorization\" not in request.headers, \"Header was not dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(\n        connector=connector,\n        base_url=\"http://host1.com\",\n        auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n    ) as client:\n        resp = await client.get(\"/path1\")\n        assert resp.status == 200\n\n\nasync def test_async_with_session() -> None:\n    async with aiohttp.ClientSession() as session:\n        pass\n\n    assert session.closed\n\n\nasync def test_session_close_awaitable() -> None:\n    session = aiohttp.ClientSession()\n    await session.close()\n\n    assert session.closed\n\n\nasync def test_close_resp_on_error_async_with_session(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.ClientSession() as session:\n        with pytest.raises(RuntimeError):\n            async with session.get(server.make_url(\"/\")) as resp:\n                resp.content.set_exception(RuntimeError())\n                await resp.read()\n\n        assert session._connector is not None\n        assert len(session._connector._conns) == 0\n\n\nasync def test_release_resp_on_normal_exit_from_cm(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.ClientSession() as session:\n        async with session.get(server.make_url(\"/\")) as resp:\n            await resp.read()\n\n        assert session._connector is not None\n        assert len(session._connector._conns) == 1\n\n\nasync def test_non_close_detached_session_on_error_cm(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    session = aiohttp.ClientSession()\n    cm = session.get(server.make_url(\"/\"))\n    assert not session.closed\n    with pytest.raises(RuntimeError):\n        async with cm as resp:\n            resp.content.set_exception(RuntimeError())\n            await resp.read()\n    assert not session.closed\n\n\nasync def test_close_detached_session_on_non_existing_addr() -> None:\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            return []\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver())\n\n    session = aiohttp.ClientSession(connector=connector)\n\n    async with session:\n        cm = session.get(\"http://non-existing.example.com\")\n        assert not session.closed\n        with pytest.raises(Exception):\n            await cm\n\n    assert session.closed\n\n\nasync def test_aiohttp_request_context_manager(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.request(\"GET\", server.make_url(\"/\")) as resp:\n        await resp.read()\n        assert resp.status == 200\n\n\nasync def test_aiohttp_request_ctx_manager_close_sess_on_error(\n    ssl_ctx: ssl.SSLContext, aiohttp_server: AiohttpServer\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n\n    cm = aiohttp.request(\"GET\", server.make_url(\"/\"))\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        async with cm:\n            pass\n\n    assert cm._session.closed\n\n\nasync def test_aiohttp_request_ctx_manager_not_found() -> None:\n    with pytest.raises(aiohttp.ClientConnectionError):\n        async with aiohttp.request(\"GET\", \"http://wrong-dns-name.com\"):\n            assert False, \"never executed\"  # pragma: no cover\n\n\nasync def test_aiohttp_request_coroutine(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    not_an_awaitable = aiohttp.request(\"GET\", server.make_url(\"/\"))\n    with pytest.raises(\n        TypeError,\n        match=\"^object _SessionRequestContextManager \"\n        \"can't be used in 'await' expression$\",\n    ):\n        await not_an_awaitable  # type: ignore[misc]\n\n    await not_an_awaitable._coro  # coroutine 'ClientSession._request' was never awaited\n    await server.close()\n\n\nasync def test_yield_from_in_session_request(aiohttp_client: AiohttpClient) -> None:\n    # a test for backward compatibility with yield from syntax\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_close_context_manager(aiohttp_client: AiohttpClient) -> None:\n    # a test for backward compatibility with yield from syntax\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    ctx = client.get(\"/\")\n    ctx.close()\n    assert not ctx._coro.cr_running\n\n\nasync def test_session_auth(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n\n    r = await client.get(\"/\")\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"Authorization\"] == \"Basic bG9naW46cGFzcw==\"\n\n\nasync def test_session_auth_override(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n\n    r = await client.get(\"/\", auth=aiohttp.BasicAuth(\"other_login\", \"pass\"))\n    assert r.status == 200\n    content = await r.json()\n    val = content[\"headers\"][\"Authorization\"]\n    assert val == \"Basic b3RoZXJfbG9naW46cGFzcw==\"\n\n\nasync def test_session_auth_header_conflict(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n    headers = {\"Authorization\": \"Basic b3RoZXJfbG9naW46cGFzcw==\"}\n    with pytest.raises(ValueError):\n        await client.get(\"/\", headers=headers)\n\n\nasync def test_session_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, headers={\"X-Real-IP\": \"192.168.0.1\"})\n\n    r = await client.get(\"/\")\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"X-Real-IP\"] == \"192.168.0.1\"\n\n\nasync def test_session_headers_merge(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(\n        app, headers=[(\"X-Real-IP\", \"192.168.0.1\"), (\"X-Sent-By\", \"requests\")]\n    )\n\n    r = await client.get(\"/\", headers={\"X-Sent-By\": \"aiohttp\"})\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"X-Real-IP\"] == \"192.168.0.1\"\n    assert content[\"headers\"][\"X-Sent-By\"] == \"aiohttp\"\n\n\nasync def test_multidict_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert await request.read() == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    data = b\"sample data\"\n\n    async with client.post(\n        \"/\", data=data, headers=MultiDict({\"Content-Length\": str(len(data))})\n    ) as r:\n        assert r.status == 200\n\n\nasync def test_request_conn_closed(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.transport is not None\n        request.transport.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ServerDisconnectedError) as excinfo:\n        resp = await client.get(\"/\")\n        await resp.read()\n\n    assert str(excinfo.value) != \"\"\n\n\nasync def test_dont_close_explicit_connector(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    r = await client.get(\"/\")\n    await r.read()\n\n    assert client.session.connector is not None\n    assert 1 == len(client.session.connector._conns)\n\n\nasync def test_server_close_keepalive_connection() -> None:\n    loop = asyncio.get_event_loop()\n\n    class Proto(asyncio.Protocol):\n        def connection_made(self, transport: asyncio.BaseTransport) -> None:\n            assert isinstance(transport, asyncio.Transport)\n            self.transp: Optional[asyncio.Transport] = transport\n            self.data = b\"\"\n\n        def data_received(self, data: bytes) -> None:\n            self.data += data\n            assert data.endswith(b\"\\r\\n\\r\\n\")\n            assert self.transp is not None\n            self.transp.write(\n                b\"HTTP/1.1 200 OK\\r\\n\"\n                b\"CONTENT-LENGTH: 2\\r\\n\"\n                b\"CONNECTION: close\\r\\n\"\n                b\"\\r\\n\"\n                b\"ok\"\n            )\n            self.transp.close()\n\n        def connection_lost(self, exc: Optional[BaseException]) -> None:\n            self.transp = None\n\n    server = await loop.create_server(Proto, \"127.0.0.1\", unused_port())\n\n    addr = server.sockets[0].getsockname()\n\n    connector = aiohttp.TCPConnector(limit=1)\n    session = aiohttp.ClientSession(connector=connector)\n\n    url = \"http://{}:{}/\".format(*addr)\n    for i in range(2):\n        r = await session.request(\"GET\", url)\n        await r.read()\n        assert 0 == len(connector._conns)\n    await session.close()\n    await connector.close()\n    server.close()\n    await server.wait_closed()\n\n\nasync def test_handle_keepalive_on_closed_connection() -> None:\n    loop = asyncio.get_event_loop()\n\n    class Proto(asyncio.Protocol):\n        def connection_made(self, transport: asyncio.BaseTransport) -> None:\n            assert isinstance(transport, asyncio.Transport)\n            self.transp: Optional[asyncio.Transport] = transport\n            self.data = b\"\"\n\n        def data_received(self, data: bytes) -> None:\n            self.data += data\n            assert data.endswith(b\"\\r\\n\\r\\n\")\n            assert self.transp is not None\n            self.transp.write(b\"HTTP/1.1 200 OK\\r\\nCONTENT-LENGTH: 2\\r\\n\\r\\nok\")\n            self.transp.close()\n\n        def connection_lost(self, exc: Optional[BaseException]) -> None:\n            self.transp = None\n\n    server = await loop.create_server(Proto, \"127.0.0.1\", unused_port())\n\n    addr = server.sockets[0].getsockname()\n\n    async with aiohttp.TCPConnector(limit=1) as connector:\n        async with aiohttp.ClientSession(connector=connector) as session:\n            url = \"http://{}:{}/\".format(*addr)\n\n            r = await session.request(\"GET\", url)\n            await r.read()\n            assert 1 == len(connector._conns)\n            closed_conn = next(iter(connector._conns.values()))\n\n            await session.request(\"GET\", url)\n            assert 1 == len(connector._conns)\n            new_conn = next(iter(connector._conns.values()))\n            assert closed_conn is not new_conn\n\n    server.close()\n    await server.wait_closed()\n\n\nasync def test_error_in_performing_request(\n    ssl_ctx: ssl.SSLContext,\n    aiohttp_client: AiohttpClient,\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    def exception_handler(loop: object, context: object) -> None:\n        \"\"\"Skip log messages about destroyed but pending tasks\"\"\"\n\n    loop = asyncio.get_event_loop()\n    loop.set_exception_handler(exception_handler)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n\n    conn = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(server, connector=conn)\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"/\")\n\n    # second try should not hang\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"/\")\n\n\nasync def test_await_after_cancelling(aiohttp_client: AiohttpClient) -> None:\n    loop = asyncio.get_event_loop()\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    fut1 = loop.create_future()\n    fut2 = loop.create_future()\n\n    async def fetch1() -> None:\n        resp = await client.get(\"/\")\n        assert resp.status == 200\n        fut1.set_result(None)\n        with pytest.raises(asyncio.CancelledError):\n            await fut2\n        resp.release()\n\n    async def fetch2() -> None:\n        await fut1\n        resp = await client.get(\"/\")\n        assert resp.status == 200\n\n    async def canceller() -> None:\n        await fut1\n        fut2.cancel()\n\n    await asyncio.gather(fetch1(), fetch2(), canceller())\n\n\nasync def test_async_payload_generator(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        assert data == b\"1234567890\" * 100\n        return web.Response()\n\n    app = web.Application()\n    app.add_routes([web.post(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def gen() -> AsyncIterator[bytes]:\n        for i in range(100):\n            yield b\"1234567890\"\n\n    async with client.post(\"/\", data=gen()) as resp:\n        assert resp.status == 200\n\n\nasync def test_read_from_closed_response(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.read()\n\n\nasync def test_read_from_closed_response2(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n        await resp.read()\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.read()\n\n\nasync def test_read_from_closed_content(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.content.readline()\n\n\nasync def test_read_timeout(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(aiohttp.ServerTimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_socket_timeout(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(SocketTimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_read_timeout_closes_connection(aiohttp_client: AiohttpClient) -> None:\n    request_count = 0\n\n    async def handler(request: web.Request) -> web.Response:\n        nonlocal request_count\n        request_count += 1\n        if request_count < 3:\n            await asyncio.sleep(0.5)\n        return web.Response(body=f\"request:{request_count}\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(total=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n    # Make sure its really closed\n    assert client.session.connector is not None\n    assert not client.session.connector._conns\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n    # Make sure its really closed\n    assert not client.session.connector._conns\n    result = await client.get(\"/\")\n    assert await result.read() == b\"request:3\"\n\n    # Make sure its not closed\n    assert client.session.connector._conns\n\n\nasync def test_read_timeout_on_prepared_response(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(aiohttp.ServerTimeoutError):\n        async with await client.get(\"/\") as resp:\n            await resp.read()\n\n\nasync def test_timeout_with_full_buffer(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        \"\"\"Server response that never ends and always has more data available.\"\"\"\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n        while True:\n            await resp.write(b\"1\" * 1000)\n            await asyncio.sleep(0.01)\n\n    async def request(client: TestClient[web.Request]) -> None:\n        timeout = aiohttp.ClientTimeout(total=0.5)\n        async with await client.get(\"/\", timeout=timeout) as resp:\n            with pytest.raises(asyncio.TimeoutError):\n                async for data in resp.content.iter_chunked(1):\n                    await asyncio.sleep(0.01)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    # wait_for() used just to ensure that a failing test doesn't hang.\n    await asyncio.wait_for(request(client), 1)\n\n\nasync def test_read_bufsize_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1234567\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, read_bufsize=2)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.content.get_read_buffer_limits() == (2, 4)\n\n\nasync def test_read_bufsize_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1234567\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", read_bufsize=4) as resp:\n        assert resp.content.get_read_buffer_limits() == (4, 8)\n\n\nasync def test_http_empty_data_text(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        ret = \"ok\" if data == b\"\" else \"fail\"\n        resp = web.Response(text=ret)\n        resp.headers[\"Content-Type\"] = request.headers[\"Content-Type\"]\n        return resp\n\n    app = web.Application()\n    app.add_routes([web.post(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.post(\"/\", data=\"\") as resp:\n        assert resp.status == 200\n        assert await resp.text() == \"ok\"\n        assert resp.headers[\"Content-Type\"] == \"text/plain; charset=utf-8\"\n\n\nasync def test_max_field_size_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8190})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8190\n\n\nasync def test_max_field_size_session_default_fail(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_max_field_size_session_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, max_field_size=8191)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8191\n\n\nasync def test_max_field_size_request_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", max_field_size=8191) as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8191\n\n\nasync def test_max_line_size_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8190)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.reason == \"x\" * 8190\n\n\nasync def test_max_line_size_session_default_fail(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8192)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_max_line_size_session_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8191)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, max_line_size=8191)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.reason == \"x\" * 8191\n\n\nasync def test_max_line_size_request_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8191)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", max_line_size=8191) as resp:\n        assert resp.reason == \"x\" * 8191\n\n\n@pytest.mark.xfail(raises=asyncio.TimeoutError, reason=\"#7599\")\nasync def test_rejected_upload(\n    aiohttp_client: AiohttpClient, tmp_path: pathlib.Path\n) -> None:\n    async def ok_handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    async def not_ok_handler(request: web.Request) -> NoReturn:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/ok\", ok_handler)\n    app.router.add_post(\"/not_ok\", not_ok_handler)\n    client = await aiohttp_client(app)\n\n    file_size_bytes = 1024 * 1024\n    file_path = tmp_path / \"uploaded.txt\"\n    file_path.write_text(\"0\" * file_size_bytes, encoding=\"utf8\")\n\n    with open(file_path, \"rb\") as file:\n        data = {\"file\": file}\n        async with await client.post(\"/not_ok\", data=data) as resp_not_ok:\n            assert 400 == resp_not_ok.status\n\n    async with await client.get(\n        \"/ok\", timeout=aiohttp.ClientTimeout(total=0.01)\n    ) as resp_ok:\n        assert 200 == resp_ok.status\n\n\nasync def test_request_with_wrong_ssl_type(aiohttp_client: AiohttpClient) -> None:\n    app = web.Application()\n    session = await aiohttp_client(app)\n\n    with pytest.raises(TypeError, match=\"ssl should be SSLContext, Fingerprint, .*\"):\n        await session.get(\"/\", ssl=42)  # type: ignore[arg-type]\n\n\n@pytest.mark.parametrize(\n    (\"value\", \"exc_type\"),\n    [(42, TypeError), (\"InvalidUrl\", InvalidURL)],\n)\nasync def test_request_with_wrong_proxy(\n    aiohttp_client: AiohttpClient, value: Union[int, str], exc_type: Type[Exception]\n) -> None:\n    app = web.Application()\n    session = await aiohttp_client(app)\n\n    with pytest.raises(exc_type):\n        await session.get(\"/\", proxy=value)  # type: ignore[arg-type]\n\n\nasync def test_raise_for_status_is_none(aiohttp_client: AiohttpClient) -> None:\n    async def handler(_: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    session = await aiohttp_client(app, raise_for_status=None)\n\n    await session.get(\"/\")\n\n\n@pytest.mark.xfail(\n    reason=\"#8395 Error message regression for large headers in 3.9.4\",\n    raises=AssertionError,\n)\nasync def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n    \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n\n    async def handler(_: web.Request) -> web.Response:\n        return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n    ) as exc_info:\n        await client.get(\"/\")\n    assert exc_info.value.status == 400\n\n\nasync def test_exception_when_read_outside_of_session(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1\" * 1000000)\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    server = await aiohttp_server(app)\n    async with aiohttp.ClientSession() as sess:\n        resp = await sess.get(server.make_url(\"/\"))\n\n    with pytest.raises(RuntimeError, match=\"Connection closed\"):\n        await resp.read()\n",
            "header": {
                "file": {
                    "path": "tests/test_client_functional.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "d9b7f82a",
                "new_commit_hash": "2e36e03b",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tests/test_client_functional.py"
            },
            "plus_file": {
                "path": "b/tests/test_client_functional.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 2961,
                            "length": 6
                        },
                        "new_range": {
                            "start": 2961,
                            "length": 138
                        },
                        "section": "async def test_drop_auth_on_redirect_to_other_host("
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        assert resp.status == 200",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "async def test_auth_persist_on_redirect_to_other_host_with_global_auth(",
                                "type": "added"
                            },
                            {
                                "content": "    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],",
                                "type": "added"
                            },
                            {
                                "content": ") -> None:",
                                "type": "added"
                            },
                            {
                                "content": "    url_from = URL(\"http://host1.com/path1\")",
                                "type": "added"
                            },
                            {
                                "content": "    url_to = URL(\"http://host2.com/path2\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    async def srv_from(request: web.Request) -> NoReturn:",
                                "type": "added"
                            },
                            {
                                "content": "        assert request.host == url_from.host",
                                "type": "added"
                            },
                            {
                                "content": "        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"",
                                "type": "added"
                            },
                            {
                                "content": "        raise web.HTTPFound(url_to)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    async def srv_to(request: web.Request) -> web.Response:",
                                "type": "added"
                            },
                            {
                                "content": "        assert request.host == url_to.host",
                                "type": "added"
                            },
                            {
                                "content": "        assert \"Authorization\" in request.headers, \"Header was dropped\"",
                                "type": "added"
                            },
                            {
                                "content": "        return web.Response()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    server_from = await create_server_for_url_and_handler(url_from, srv_from)",
                                "type": "added"
                            },
                            {
                                "content": "    server_to = await create_server_for_url_and_handler(url_to, srv_to)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    assert (",
                                "type": "added"
                            },
                            {
                                "content": "        url_from.host != url_to.host or server_from.scheme != server_to.scheme",
                                "type": "added"
                            },
                            {
                                "content": "    ), \"Invalid test case, host or scheme must differ\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    protocol_port_map = {",
                                "type": "added"
                            },
                            {
                                "content": "        \"http\": 80,",
                                "type": "added"
                            },
                            {
                                "content": "        \"https\": 443,",
                                "type": "added"
                            },
                            {
                                "content": "    }",
                                "type": "added"
                            },
                            {
                                "content": "    etc_hosts = {",
                                "type": "added"
                            },
                            {
                                "content": "        (url_from.host, protocol_port_map[server_from.scheme]): server_from,",
                                "type": "added"
                            },
                            {
                                "content": "        (url_to.host, protocol_port_map[server_to.scheme]): server_to,",
                                "type": "added"
                            },
                            {
                                "content": "    }",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    class FakeResolver(AbstractResolver):",
                                "type": "added"
                            },
                            {
                                "content": "        async def resolve(",
                                "type": "added"
                            },
                            {
                                "content": "            self,",
                                "type": "added"
                            },
                            {
                                "content": "            host: str,",
                                "type": "added"
                            },
                            {
                                "content": "            port: int = 0,",
                                "type": "added"
                            },
                            {
                                "content": "            family: socket.AddressFamily = socket.AF_INET,",
                                "type": "added"
                            },
                            {
                                "content": "        ) -> List[ResolveResult]:",
                                "type": "added"
                            },
                            {
                                "content": "            server = etc_hosts[(host, port)]",
                                "type": "added"
                            },
                            {
                                "content": "            assert server.port is not None",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            return [",
                                "type": "added"
                            },
                            {
                                "content": "                {",
                                "type": "added"
                            },
                            {
                                "content": "                    \"hostname\": host,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"host\": server.host,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"port\": server.port,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"family\": socket.AF_INET,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"proto\": 0,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"flags\": socket.AI_NUMERICHOST,",
                                "type": "added"
                            },
                            {
                                "content": "                }",
                                "type": "added"
                            },
                            {
                                "content": "            ]",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        async def close(self) -> None:",
                                "type": "added"
                            },
                            {
                                "content": "            \"\"\"Dummy\"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    async with aiohttp.ClientSession(",
                                "type": "added"
                            },
                            {
                                "content": "        connector=connector, auth=aiohttp.BasicAuth(\"user\", \"pass\")",
                                "type": "added"
                            },
                            {
                                "content": "    ) as client:",
                                "type": "added"
                            },
                            {
                                "content": "        resp = await client.get(url_from)",
                                "type": "added"
                            },
                            {
                                "content": "        assert resp.status == 200",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "async def test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url(",
                                "type": "added"
                            },
                            {
                                "content": "    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],",
                                "type": "added"
                            },
                            {
                                "content": ") -> None:",
                                "type": "added"
                            },
                            {
                                "content": "    url_from = URL(\"http://host1.com/path1\")",
                                "type": "added"
                            },
                            {
                                "content": "    url_to = URL(\"http://host2.com/path2\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    async def srv_from(request: web.Request) -> NoReturn:",
                                "type": "added"
                            },
                            {
                                "content": "        assert request.host == url_from.host",
                                "type": "added"
                            },
                            {
                                "content": "        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"",
                                "type": "added"
                            },
                            {
                                "content": "        raise web.HTTPFound(url_to)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    async def srv_to(request: web.Request) -> web.Response:",
                                "type": "added"
                            },
                            {
                                "content": "        assert request.host == url_to.host",
                                "type": "added"
                            },
                            {
                                "content": "        assert \"Authorization\" not in request.headers, \"Header was not dropped\"",
                                "type": "added"
                            },
                            {
                                "content": "        return web.Response()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    server_from = await create_server_for_url_and_handler(url_from, srv_from)",
                                "type": "added"
                            },
                            {
                                "content": "    server_to = await create_server_for_url_and_handler(url_to, srv_to)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    assert (",
                                "type": "added"
                            },
                            {
                                "content": "        url_from.host != url_to.host or server_from.scheme != server_to.scheme",
                                "type": "added"
                            },
                            {
                                "content": "    ), \"Invalid test case, host or scheme must differ\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    protocol_port_map = {",
                                "type": "added"
                            },
                            {
                                "content": "        \"http\": 80,",
                                "type": "added"
                            },
                            {
                                "content": "        \"https\": 443,",
                                "type": "added"
                            },
                            {
                                "content": "    }",
                                "type": "added"
                            },
                            {
                                "content": "    etc_hosts = {",
                                "type": "added"
                            },
                            {
                                "content": "        (url_from.host, protocol_port_map[server_from.scheme]): server_from,",
                                "type": "added"
                            },
                            {
                                "content": "        (url_to.host, protocol_port_map[server_to.scheme]): server_to,",
                                "type": "added"
                            },
                            {
                                "content": "    }",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    class FakeResolver(AbstractResolver):",
                                "type": "added"
                            },
                            {
                                "content": "        async def resolve(",
                                "type": "added"
                            },
                            {
                                "content": "            self,",
                                "type": "added"
                            },
                            {
                                "content": "            host: str,",
                                "type": "added"
                            },
                            {
                                "content": "            port: int = 0,",
                                "type": "added"
                            },
                            {
                                "content": "            family: socket.AddressFamily = socket.AF_INET,",
                                "type": "added"
                            },
                            {
                                "content": "        ) -> List[ResolveResult]:",
                                "type": "added"
                            },
                            {
                                "content": "            server = etc_hosts[(host, port)]",
                                "type": "added"
                            },
                            {
                                "content": "            assert server.port is not None",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            return [",
                                "type": "added"
                            },
                            {
                                "content": "                {",
                                "type": "added"
                            },
                            {
                                "content": "                    \"hostname\": host,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"host\": server.host,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"port\": server.port,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"family\": socket.AF_INET,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"proto\": 0,",
                                "type": "added"
                            },
                            {
                                "content": "                    \"flags\": socket.AI_NUMERICHOST,",
                                "type": "added"
                            },
                            {
                                "content": "                }",
                                "type": "added"
                            },
                            {
                                "content": "            ]",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        async def close(self) -> None:",
                                "type": "added"
                            },
                            {
                                "content": "            \"\"\"Dummy\"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    async with aiohttp.ClientSession(",
                                "type": "added"
                            },
                            {
                                "content": "        connector=connector,",
                                "type": "added"
                            },
                            {
                                "content": "        base_url=\"http://host1.com\",",
                                "type": "added"
                            },
                            {
                                "content": "        auth=aiohttp.BasicAuth(\"user\", \"pass\"),",
                                "type": "added"
                            },
                            {
                                "content": "    ) as client:",
                                "type": "added"
                            },
                            {
                                "content": "        resp = await client.get(\"/path1\")",
                                "type": "added"
                            },
                            {
                                "content": "        assert resp.status == 200",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "async def test_async_with_session() -> None:",
                                "type": "context"
                            },
                            {
                                "content": "    async with aiohttp.ClientSession() as session:",
                                "type": "context"
                            },
                            {
                                "content": "        pass",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "tests/test_client_functional.py",
                            "type": "function",
                            "name": "test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url",
                            "content": "async def test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n) -> None:\n    url_from = URL(\"http://host1.com/path1\")\n    url_to = URL(\"http://host2.com/path2\")\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        assert \"Authorization\" not in request.headers, \"Header was not dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(\n        connector=connector,\n        base_url=\"http://host1.com\",\n        auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n    ) as client:\n        resp = await client.get(\"/path1\")\n        assert resp.status == 200",
                            "ast_type_str": "AsyncFunctionDef",
                            "start_lineno": 3029,
                            "end_lineno": 3093,
                            "parent": null
                        },
                        {
                            "file_name": "tests/test_client_functional.py",
                            "type": "function",
                            "name": "test_auth_persist_on_redirect_to_other_host_with_global_auth",
                            "content": "async def test_auth_persist_on_redirect_to_other_host_with_global_auth(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n) -> None:\n    url_from = URL(\"http://host1.com/path1\")\n    url_to = URL(\"http://host2.com/path2\")\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        assert \"Authorization\" in request.headers, \"Header was dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(\n        connector=connector, auth=aiohttp.BasicAuth(\"user\", \"pass\")\n    ) as client:\n        resp = await client.get(url_from)\n        assert resp.status == 200",
                            "ast_type_str": "AsyncFunctionDef",
                            "start_lineno": 2964,
                            "end_lineno": 3026,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "f569894caa7cfbc2ec03fb5eed6021b9899dc4b4^",
    "new_commit_hash": "f569894caa7cfbc2ec03fb5eed6021b9899dc4b4",
    "commit_message": "Fix auth reset logic during redirects to different origin when _base_url set (#8966)",
    "commit_date": "2024-09-01T20:57:48+01:00",
    "metadata": {}
}
{
    "repo_name": "aiohttp",
    "new_commit_hash": "f569894caa7cfbc2ec03fb5eed6021b9899dc4b4",
    "test_file_codes": [
        "# HTTP client functional tests against aiohttp.web server\n\nimport asyncio\nimport datetime\nimport http.cookies\nimport io\nimport json\nimport pathlib\nimport socket\nimport ssl\nimport sys\nimport tarfile\nimport time\nimport zipfile\nfrom typing import (\n    Any,\n    AsyncIterator,\n    Awaitable,\n    Callable,\n    Dict,\n    List,\n    NoReturn,\n    Optional,\n    Type,\n    Union,\n)\nfrom unittest import mock\n\nimport pytest\nimport trustme\nfrom multidict import MultiDict\nfrom pytest_mock import MockerFixture\nfrom yarl import URL\n\nimport aiohttp\nfrom aiohttp import Fingerprint, ServerFingerprintMismatch, hdrs, web\nfrom aiohttp.abc import AbstractResolver, ResolveResult\nfrom aiohttp.client_exceptions import (\n    InvalidURL,\n    InvalidUrlClientError,\n    InvalidUrlRedirectClientError,\n    NonHttpUrlClientError,\n    NonHttpUrlRedirectClientError,\n    SocketTimeoutError,\n    TooManyRedirects,\n)\nfrom aiohttp.pytest_plugin import AiohttpClient, AiohttpServer\nfrom aiohttp.test_utils import TestClient, TestServer, unused_port\nfrom aiohttp.typedefs import Handler\n\n\n@pytest.fixture\ndef here() -> pathlib.Path:\n    return pathlib.Path(__file__).parent\n\n\n@pytest.fixture\ndef fname(here: pathlib.Path) -> pathlib.Path:\n    return here / \"conftest.py\"\n\n\nasync def test_keepalive_two_requests_success(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_keepalive_after_head_requests_success(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    app.router.add_route(\"HEAD\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.head(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert 1 == cnt_conn_reuse\n\n\n@pytest.mark.parametrize(\"status\", (101, 204, 304))\nasync def test_keepalive_after_empty_body_status(\n    aiohttp_client: AiohttpClient, status: int\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(status=status)\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert cnt_conn_reuse == 1\n\n\n@pytest.mark.parametrize(\"status\", (101, 204, 304))\nasync def test_keepalive_after_empty_body_status_stream_response(\n    aiohttp_client: AiohttpClient, status: int\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        stream_response = web.StreamResponse(status=status)\n        await stream_response.prepare(request)\n        return stream_response\n\n    cnt_conn_reuse = 0\n\n    async def on_reuseconn(session: object, ctx: object, params: object) -> None:\n        nonlocal cnt_conn_reuse\n        cnt_conn_reuse += 1\n\n    trace_config = aiohttp.TraceConfig()\n    trace_config._on_connection_reuseconn.append(on_reuseconn)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(\n        app, connector=connector, trace_configs=[trace_config]\n    )\n\n    resp1 = await client.get(\"/\")\n    await resp1.read()\n    resp2 = await client.get(\"/\")\n    await resp2.read()\n\n    assert cnt_conn_reuse == 1\n\n\nasync def test_keepalive_response_released(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    resp1.release()\n    resp2 = await client.get(\"/\")\n    resp2.release()\n\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_upgrade_connection_not_released_after_read(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(\n            status=101, headers={\"Connection\": \"Upgrade\", \"Upgrade\": \"tcp\"}\n        )\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    await resp.read()\n    assert resp.connection is not None\n    assert not resp.closed\n\n\nasync def test_keepalive_server_force_close_connection(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        response = web.Response(body=b\"OK\")\n        response.force_close()\n        return response\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    resp1.close()\n    resp2 = await client.get(\"/\")\n    resp2.close()\n\n    assert client._session.connector is not None\n    assert 0 == len(client._session.connector._conns)\n\n\nasync def test_keepalive_timeout_async_sleep() -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001)\n    await runner.setup()\n\n    port = unused_port()\n    site = web.TCPSite(runner, host=\"localhost\", port=port)\n    await site.start()\n\n    try:\n        async with aiohttp.ClientSession() as sess:\n            resp1 = await sess.get(f\"http://localhost:{port}/\")\n            await resp1.read()\n            # wait for server keepalive_timeout\n            await asyncio.sleep(0.01)\n            resp2 = await sess.get(f\"http://localhost:{port}/\")\n            await resp2.read()\n    finally:\n        await asyncio.gather(runner.shutdown(), site.stop())\n\n\n@pytest.mark.skipif(\n    sys.version_info[:2] == (3, 11),\n    reason=\"https://github.com/pytest-dev/pytest/issues/10763\",\n)\nasync def test_keepalive_timeout_sync_sleep() -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001)\n    await runner.setup()\n\n    port = unused_port()\n    site = web.TCPSite(runner, host=\"localhost\", port=port)\n    await site.start()\n\n    try:\n        async with aiohttp.ClientSession() as sess:\n            resp1 = await sess.get(f\"http://localhost:{port}/\")\n            await resp1.read()\n            # wait for server keepalive_timeout\n            # time.sleep is a more challenging scenario than asyncio.sleep\n            time.sleep(0.01)\n            resp2 = await sess.get(f\"http://localhost:{port}/\")\n            await resp2.read()\n    finally:\n        await asyncio.gather(runner.shutdown(), site.stop())\n\n\nasync def test_release_early(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        await request.read()\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n    resp = await client.get(\"/\")\n    assert resp.closed\n    await resp.wait_for_close()\n    assert client._session.connector is not None\n    assert 1 == len(client._session.connector._conns)\n\n\nasync def test_HTTP_304(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(status=304)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    content = await resp.read()\n    assert content == b\"\"\n\n\nasync def test_stream_request_on_server_eof(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"OK\", status=200)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    app.add_routes([web.put(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def data_gen() -> AsyncIterator[bytes]:\n        for _ in range(2):\n            yield b\"just data\"\n            await asyncio.sleep(0.1)\n\n    assert client.session.connector is not None\n    async with client.put(\"/\", data=data_gen()) as resp:\n        assert 200 == resp.status\n        assert len(client.session.connector._acquired) == 1\n        conn = next(iter(client.session.connector._acquired))\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n    # Connection should have been reused\n    conns = next(iter(client.session.connector._conns.values()))\n    assert len(conns) == 1\n    assert conns[0][0] is conn\n\n\nasync def test_stream_request_on_server_eof_nested(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"OK\", status=200)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    app.add_routes([web.put(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def data_gen() -> AsyncIterator[bytes]:\n        for _ in range(2):\n            yield b\"just data\"\n            await asyncio.sleep(0.1)\n\n    async with client.put(\"/\", data=data_gen()) as resp:\n        assert 200 == resp.status\n        async with client.get(\"/\") as resp:\n            assert 200 == resp.status\n\n    # Should be 2 separate connections\n    assert client.session.connector is not None\n    conns = next(iter(client.session.connector._conns.values()))\n    assert len(conns) == 2\n\n\nasync def test_HTTP_304_WITH_BODY(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        return web.Response(body=b\"test\", status=304)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    content = await resp.read()\n    assert content == b\"\"\n\n\nasync def test_auto_header_user_agent(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"aiohttp\" in request.headers[\"user-agent\"]\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_auto_headers_user_agent(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.USER_AGENT not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", skip_auto_headers=[\"user-agent\"]) as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_default_auto_headers_user_agent(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.USER_AGENT not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, skip_auto_headers=[\"user-agent\"])\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_skip_auto_headers_content_type(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert hdrs.CONTENT_TYPE not in request.headers\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", skip_auto_headers=[\"content-type\"]) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_bytesio(aiohttp_client: AiohttpClient) -> None:\n    data = b\"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert len(data) == request.content_length\n        val = await request.read()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(data) as file_handle:\n        async with client.post(\"/\", data=file_handle) as resp:\n            assert 200 == resp.status\n\n\nasync def test_post_data_with_bytesio_file(aiohttp_client: AiohttpClient) -> None:\n    data = b\"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        post_data = await request.post()\n        assert [\"file\"] == list(post_data.keys())\n        file_field = post_data[\"file\"]\n        assert isinstance(file_field, web.FileField)\n        assert data == file_field.file.read()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(data) as file_handle:\n        async with client.post(\"/\", data={\"file\": file_handle}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_post_data_stringio(aiohttp_client: AiohttpClient) -> None:\n    data = \"some buffer\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert len(data) == request.content_length\n        assert request.headers[\"CONTENT-TYPE\"] == \"text/plain; charset=utf-8\"\n        val = await request.text()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data=io.StringIO(data)) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_textio_encoding(aiohttp_client: AiohttpClient) -> None:\n    data = \"текст\"\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.headers[\"CONTENT-TYPE\"] == \"text/plain; charset=koi8-r\"\n        val = await request.text()\n        assert data == val\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    pl = aiohttp.TextIOPayload(io.StringIO(data), encoding=\"koi8-r\")\n    async with client.post(\"/\", data=pl) as resp:\n        assert 200 == resp.status\n\n\nasync def test_post_data_zipfile_filelike(aiohttp_client: AiohttpClient) -> None:\n    data = b\"This is a zip file payload text file.\"\n\n    async def handler(request: web.Request) -> web.Response:\n        val = await request.read()\n        assert data == val, \"Transmitted zipfile member failed to match original data.\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    buf = io.BytesIO()\n    with zipfile.ZipFile(file=buf, mode=\"w\") as zf:\n        with zf.open(\"payload1.txt\", mode=\"w\") as zip_filelike_writing:\n            zip_filelike_writing.write(data)\n\n    buf.seek(0)\n    zf = zipfile.ZipFile(file=buf, mode=\"r\")\n    resp = await client.post(\"/\", data=zf.open(\"payload1.txt\"))\n    assert 200 == resp.status\n\n\nasync def test_post_data_tarfile_filelike(aiohttp_client: AiohttpClient) -> None:\n    data = b\"This is a tar file payload text file.\"\n\n    async def handler(request: web.Request) -> web.Response:\n        val = await request.read()\n        assert data == val, \"Transmitted tarfile member failed to match original data.\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"POST\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    buf = io.BytesIO()\n    with tarfile.open(fileobj=buf, mode=\"w\") as tf:\n        ti = tarfile.TarInfo(name=\"payload1.txt\")\n        ti.size = len(data)\n        tf.addfile(tarinfo=ti, fileobj=io.BytesIO(data))\n\n    # Random-access tarfile.\n    buf.seek(0)\n    tf = tarfile.open(fileobj=buf, mode=\"r:\")\n    resp = await client.post(\"/\", data=tf.extractfile(\"payload1.txt\"))\n    assert 200 == resp.status\n\n    # Streaming tarfile.\n    buf.seek(0)\n    tf = tarfile.open(fileobj=buf, mode=\"r|\")\n    for entry in tf:\n        resp = await client.post(\"/\", data=tf.extractfile(entry))\n        assert 200 == resp.status\n\n\nasync def test_ssl_client(\n    aiohttp_server: AiohttpServer,\n    ssl_ctx: ssl.SSLContext,\n    aiohttp_client: AiohttpClient,\n    client_ssl_ctx: ssl.SSLContext,\n) -> None:\n    connector = aiohttp.TCPConnector(ssl=client_ssl_ctx)\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"Test message\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"Test message\"\n\n\nasync def test_tcp_connector_fingerprint_ok(\n    aiohttp_server: AiohttpServer,\n    aiohttp_client: AiohttpClient,\n    ssl_ctx: ssl.SSLContext,\n    tls_certificate_fingerprint_sha256: bytes,\n) -> None:\n    tls_fingerprint = Fingerprint(tls_certificate_fingerprint_sha256)\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=\"Test message\")\n\n    connector = aiohttp.TCPConnector(ssl=tls_fingerprint)\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_tcp_connector_fingerprint_fail(\n    aiohttp_server: AiohttpServer,\n    aiohttp_client: AiohttpClient,\n    ssl_ctx: ssl.SSLContext,\n    tls_certificate_fingerprint_sha256: bytes,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    bad_fingerprint = b\"\\x00\" * len(tls_certificate_fingerprint_sha256)\n\n    connector = aiohttp.TCPConnector(ssl=Fingerprint(bad_fingerprint))\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n    client = await aiohttp_client(server, connector=connector)\n\n    with pytest.raises(ServerFingerprintMismatch) as cm:\n        await client.get(\"/\")\n    exc = cm.value\n    assert exc.expected == bad_fingerprint\n    assert exc.got == tls_certificate_fingerprint_sha256\n\n\nasync def test_format_task_get(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_server(app)\n    client = aiohttp.ClientSession()\n    task = asyncio.create_task(client.get(server.make_url(\"/\")))\n    assert f\"{task}\".startswith(\"<Task pending\")\n    resp = await task\n    resp.close()\n    await client.close()\n\n\nasync def test_str_params(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"q=t est\" in request.rel_url.query_string\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", params=\"q=t+est\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_drop_params_on_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok?a=redirect\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        assert request.rel_url.query_string == \"a=redirect\"\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\", params={\"a\": \"initial\"}) as resp:\n        assert resp.status == 200\n\n\nasync def test_drop_fragment_on_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok#fragment\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\") as resp:\n        assert resp.status == 200\n        assert resp.url.path == \"/ok\"\n\n\nasync def test_drop_fragment(aiohttp_client: AiohttpClient) -> None:\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/ok#fragment\") as resp:\n        assert resp.status == 200\n        assert resp.url.path == \"/ok\"\n\n\nasync def test_history(aiohttp_client: AiohttpClient) -> None:\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers={\"Location\": \"/ok\"})\n\n    async def handler_ok(request: web.Request) -> web.Response:\n        return web.Response(status=200)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/ok\", handler_ok)\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/ok\") as resp:\n        assert len(resp.history) == 0\n        assert resp.status == 200\n\n    async with client.get(\"/redirect\") as resp_redirect:\n        assert len(resp_redirect.history) == 1\n        assert resp_redirect.history[0].status == 301\n        assert resp_redirect.status == 200\n\n\nasync def test_keepalive_closed_by_server(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        body = await request.read()\n        assert b\"\" == body\n        resp = web.Response(body=b\"OK\")\n        resp.force_close()\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    connector = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(app, connector=connector)\n\n    resp1 = await client.get(\"/\")\n    val1 = await resp1.read()\n    assert val1 == b\"OK\"\n    resp2 = await client.get(\"/\")\n    val2 = await resp2.read()\n    assert val2 == b\"OK\"\n\n    assert client._session.connector is not None\n    assert 0 == len(client._session.connector._conns)\n\n\nasync def test_wait_for(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"OK\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await asyncio.wait_for(client.get(\"/\"), 10)\n    assert resp.status == 200\n    txt = await resp.text()\n    assert txt == \"OK\"\n\n\nasync def test_raw_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n        raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers)\n        assert raw_headers == (\n            (b\"Content-Length\", b\"0\"),\n            (b\"Date\", mock.ANY),\n            (b\"Server\", mock.ANY),\n        )\n\n\nasync def test_host_header_first(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert list(request.headers)[0] == hdrs.HOST\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_empty_header_values(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response()\n        resp.headers[\"X-Empty\"] = \"\"\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n        raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers)\n        assert raw_headers == (\n            (b\"X-Empty\", b\"\"),\n            (b\"Content-Length\", b\"0\"),\n            (b\"Date\", mock.ANY),\n            (b\"Server\", mock.ANY),\n        )\n\n\nasync def test_204_with_gzipped_content_encoding(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=204)\n        resp.content_length = 0\n        resp.content_type = \"application/json\"\n        # resp.enable_compression(web.ContentCoding.gzip)\n        resp.headers[\"Content-Encoding\"] = \"gzip\"\n        await resp.prepare(request)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"DELETE\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.delete(\"/\") as resp:\n        assert resp.status == 204\n        assert resp.closed\n\n\nasync def test_timeout_on_reading_headers(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\", timeout=aiohttp.ClientTimeout(total=0.01))\n\n\nasync def test_timeout_on_conn_reading_headers(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    # tests case where user did not set a connection timeout\n\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    conn = aiohttp.TCPConnector()\n    client = await aiohttp_client(app, connector=conn)\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\", timeout=aiohttp.ClientTimeout(total=0.01))\n\n\nasync def test_timeout_on_session_read_timeout(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    conn = aiohttp.TCPConnector()\n    client = await aiohttp_client(\n        app, connector=conn, timeout=aiohttp.ClientTimeout(sock_read=0.01)\n    )\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_read_timeout_between_chunks(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        # write data 4 times, with pauses. Total time 2 seconds.\n        for _ in range(4):\n            await asyncio.sleep(0.5)\n            await resp.write(b\"data\\n\")\n        return resp\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    # A timeout of 0.2 seconds should apply per read.\n    timeout = aiohttp.ClientTimeout(sock_read=1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    res = b\"\"\n    async with await client.get(\"/\") as resp:\n        res += await resp.read()\n\n    assert res == b\"data\\n\" * 4\n\n\nasync def test_read_timeout_on_reading_chunks(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        await resp.write(b\"data\\n\")\n        await asyncio.sleep(1)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    # A timeout of 0.2 seconds should apply per read.\n    timeout = aiohttp.ClientTimeout(sock_read=0.2)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    async with await client.get(\"/\") as resp:\n        assert (await resp.content.read(5)) == b\"data\\n\"\n        with pytest.raises(asyncio.TimeoutError):\n            await resp.content.read()\n\n\nasync def test_read_timeout_on_write(aiohttp_client: AiohttpClient) -> None:\n    async def gen_payload() -> AsyncIterator[bytes]:\n        # Delay writing to ensure read timeout isn't triggered before writing completes.\n        await asyncio.sleep(0.5)\n        yield b\"foo\"\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=await request.read())\n\n    app = web.Application()\n    app.router.add_put(\"/\", handler)\n\n    timeout = aiohttp.ClientTimeout(total=None, sock_read=0.1)\n    client = await aiohttp_client(app)\n    async with client.put(\"/\", data=gen_payload(), timeout=timeout) as resp:\n        result = await resp.read()  # Should not trigger a read timeout.\n    assert result == b\"foo\"\n\n\nasync def test_timeout_on_reading_data(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    loop = asyncio.get_event_loop()\n\n    fut = loop.create_future()\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        fut.set_result(None)\n        await asyncio.sleep(0.2)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", timeout=aiohttp.ClientTimeout(1))\n    await fut\n\n    with pytest.raises(asyncio.TimeoutError):\n        await resp.read()\n\n\nasync def test_timeout_none(\n    aiohttp_client: AiohttpClient, mocker: MockerFixture\n) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n        return resp\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\", timeout=None) as resp:\n        assert resp.status == 200\n\n\nasync def test_readline_error_on_conn_close(aiohttp_client: AiohttpClient) -> None:\n    loop = asyncio.get_event_loop()\n\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n\n        # make sure connection is closed by client.\n        with pytest.raises(aiohttp.ServerDisconnectedError):\n            for _ in range(10):\n                await resp.write(b\"data\\n\")\n                await asyncio.sleep(0.5)\n        assert False\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        timer_started = False\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        with pytest.raises(aiohttp.ClientConnectionError):\n            while True:\n                data = await resp.content.readline()\n                data = data.strip()\n                assert data\n                assert data == b\"data\"\n                if not timer_started:\n                    loop.call_later(1.0, resp.release)\n                    timer_started = True\n    finally:\n        await session.close()\n\n\nasync def test_no_error_on_conn_close_if_eof(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp_ = web.StreamResponse()\n        await resp_.prepare(request)\n        await resp_.write(b\"data\\n\")\n        await asyncio.sleep(0.5)\n        return resp_\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        while True:\n            data = await resp.content.readline()\n            data = data.strip()\n            if not data:\n                break\n            assert data == b\"data\"\n\n        assert resp.content.exception() is None\n    finally:\n        await session.close()\n\n\nasync def test_error_not_overwrote_on_conn_close(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp_ = web.StreamResponse()\n        await resp_.prepare(request)\n        return resp_\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    server = await aiohttp_client(app)\n\n    session = aiohttp.ClientSession()\n    try:\n        url, headers = server.make_url(\"/\"), {\"Connection\": \"Keep-alive\"}\n        resp = await session.get(url, headers=headers)\n        resp.content.set_exception(ValueError())\n    finally:\n        await session.close()\n\n    assert isinstance(resp.content.exception(), ValueError)\n\n\nasync def test_HTTP_200_OK_METHOD(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n\n    client = await aiohttp_client(app)\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        resp = await client.request(meth, \"/\")\n        assert resp.status == 200\n        assert len(resp.history) == 0\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_HTTP_200_OK_METHOD_connector(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    conn = aiohttp.TCPConnector()\n    conn.clear_dns_cache()\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n    client = await aiohttp_client(app, connector=conn)\n\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\"):\n        resp = await client.request(meth, \"/\")\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        assert resp.status == 200\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_HTTP_302_REDIRECT_GET(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/redirect\") as resp:\n        assert 200 == resp.status\n        assert 1 == len(resp.history)\n\n\nasync def test_HTTP_302_REDIRECT_HEAD(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n    app.router.add_head(\"/\", handler)\n    app.router.add_head(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    async with client.request(\"head\", \"/redirect\") as resp:\n        assert 200 == resp.status\n        assert 1 == len(resp.history)\n        assert resp.method == \"HEAD\"\n\n\nasync def test_HTTP_302_REDIRECT_NON_HTTP(aiohttp_client: AiohttpClient) -> None:\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"ftp://127.0.0.1/test/\")\n\n    app = web.Application()\n    app.router.add_get(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(NonHttpUrlRedirectClientError):\n        await client.get(\"/redirect\")\n\n\nasync def test_HTTP_302_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=\"/\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\")\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"GET\"\n    resp.close()\n\n\nasync def test_HTTP_302_REDIRECT_POST_with_content_length_hdr(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPFound(location=\"/\")\n\n    data = json.dumps({\"some\": \"data\"})\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\n        \"/redirect\", data=data, headers={\"Content-Length\": str(len(data))}\n    )\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"GET\"\n    resp.close()\n\n\nasync def test_HTTP_307_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPTemporaryRedirect(location=\"/\")\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"POST\"\n    resp.close()\n\n\nasync def test_HTTP_308_PERMANENT_REDIRECT_POST(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        await request.read()\n        raise web.HTTPPermanentRedirect(location=\"/\")\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    app.router.add_post(\"/redirect\", redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/redirect\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert 1 == len(resp.history)\n    txt = await resp.text()\n    assert txt == \"POST\"\n    resp.close()\n\n\nasync def test_HTTP_302_max_redirects(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    async def redirect(request: web.Request) -> NoReturn:\n        count = int(request.match_info[\"count\"])\n        assert count\n        raise web.HTTPFound(location=f\"/redirect/{count - 1}\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(r\"/redirect/{count:\\d+}\", redirect)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(TooManyRedirects) as ctx:\n        await client.get(\"/redirect/5\", max_redirects=2)\n    assert 2 == len(ctx.value.history)\n    assert ctx.value.request_info.url.path == \"/redirect/5\"\n    assert ctx.value.request_info.method == \"GET\"\n\n\nasync def test_HTTP_200_GET_WITH_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", params={\"q\": \"test\"})\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"q=test\"\n    resp.close()\n\n\nasync def test_HTTP_200_GET_WITH_MultiDict_PARAMS(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\", params=MultiDict([(\"q\", \"test\"), (\"q\", \"test2\")]))\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"q=test&q=test2\"\n    resp.close()\n\n\nasync def test_HTTP_200_GET_WITH_MIXED_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(\n            text=\"&\".join(k + \"=\" + v for k, v in request.query.items())\n        )\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/?test=true\", params={\"q\": \"test\"})\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"test=true&q=test\"\n    resp.close()\n\n\nasync def test_POST_DATA(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/\", data={\"some\": \"data\"})\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n\nasync def test_POST_DATA_with_explicit_formdata(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"text\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"name\": \"text\"}\n    resp.close()\n\n\nasync def test_POST_DATA_with_charset(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        mp = await request.multipart()\n        part = await mp.next()\n        assert isinstance(part, aiohttp.BodyPartReader)\n        text = await part.text()\n        return web.Response(text=text)\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"текст\", content_type=\"text/plain; charset=koi8-r\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_DATA_formdats_with_charset(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        mp = await request.post()\n        assert \"name\" in mp\n        assert isinstance(mp[\"name\"], str)\n        return web.Response(text=mp[\"name\"])\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData(charset=\"koi8-r\")\n    form.add_field(\"name\", \"текст\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_DATA_with_charset_post(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"name\"], str)\n        return web.Response(text=data[\"name\"])\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    form = aiohttp.FormData()\n    form.add_field(\"name\", \"текст\", content_type=\"text/plain; charset=koi8-r\")\n\n    resp = await client.post(\"/\", data=form)\n    assert 200 == resp.status\n    content = await resp.text()\n    assert content == \"текст\"\n    resp.close()\n\n\nasync def test_POST_MultiDict(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data == MultiDict([(\"q\", \"test1\"), (\"q\", \"test2\")])\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\n        \"/\", data=MultiDict([(\"q\", \"test1\"), (\"q\", \"test2\")])\n    ) as resp:\n        assert 200 == resp.status\n\n\nasync def test_POST_DATA_DEFLATE(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        return web.json_response(dict(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    # True is not a valid type, but still tested for backwards compatibility.\n    resp = await client.post(\"/\", data={\"some\": \"data\"}, compress=True)  # type: ignore[arg-type]\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n\nasync def test_POST_FILES(aiohttp_client: AiohttpClient, fname: pathlib.Path) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            content1 = f.read()\n        content2 = data[\"some\"].file.read()\n        assert content1 == content2\n        assert isinstance(data[\"test\"], web.FileField)\n        assert data[\"test\"].file.read() == b\"data\"\n        assert isinstance(data[\"some\"], web.FileField)\n        data[\"some\"].file.close()\n        data[\"test\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data={\"some\": f, \"test\": io.BytesIO(b\"data\")}, chunked=True\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_DEFLATE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            content1 = f.read()\n        content2 = data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        assert content1 == content2\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data={\"some\": f}, chunked=True, compress=\"deflate\"\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_bytes(aiohttp_client: AiohttpClient) -> None:\n    body = b\"0\" * 12345\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        assert body == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data=body) as resp:\n        assert 200 == resp.status\n\n\nasync def test_POST_bytes_too_large(aiohttp_client: AiohttpClient) -> None:\n    body = b\"0\" * (2**20 + 1)\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.content.read()\n        assert body == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.warns(ResourceWarning):\n        resp = await client.post(\"/\", data=body)\n\n    assert 200 == resp.status\n    resp.close()\n\n\nasync def test_POST_FILES_STR(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        with fname.open(\"rb\") as f:\n            content1 = f.read().decode()\n        content2 = data[\"some\"]\n        assert content1 == content2\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data={\"some\": f.read().decode()}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_STR_SIMPLE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f.read()) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_LIST(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert fname.name == data[\"some\"].filename\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=[(\"some\", f)]) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_CT(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"some\"], web.FileField)\n        assert fname.name == data[\"some\"].filename\n        assert \"text/plain\" == data[\"some\"].content_type\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data[\"some\"].file.read()\n        data[\"some\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        form = aiohttp.FormData()\n        form.add_field(\"some\", f, content_type=\"text/plain\")\n        async with client.post(\"/\", data=form) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.text()\n        with fname.open(\"rb\") as f:\n            content = f.read().decode()\n            assert content == data\n        # if system cannot determine 'text/x-python' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"text/plain\",\n            \"application/octet-stream\",\n            \"text/x-python\",\n        ]\n        assert \"content-disposition\" not in request.headers\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE_content_disposition(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.text()\n        with fname.open(\"rb\") as f:\n            content = f.read().decode()\n            assert content == data\n        # if system cannot determine 'application/pgp-keys' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"text/plain\",\n            \"application/octet-stream\",\n            \"text/x-python\",\n        ]\n        assert request.headers[\"content-disposition\"] == (\n            'inline; filename=\"conftest.py\"'\n        )\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\n            \"/\", data=aiohttp.get_payload(f, disposition=\"inline\")\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_SINGLE_BINARY(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        with fname.open(\"rb\") as f:\n            content = f.read()\n        assert content == data\n        # if system cannot determine 'application/pgp-keys' MIME type\n        # then use 'application/octet-stream' default\n        assert request.content_type in [\n            \"application/pgp-keys\",\n            \"text/plain\",\n            \"text/x-python\",\n            \"application/octet-stream\",\n        ]\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data=f) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_IO(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert isinstance(data[\"unknown\"], web.FileField)\n        assert b\"data\" == data[\"unknown\"].file.read()\n        assert data[\"unknown\"].content_type == \"application/octet-stream\"\n        assert data[\"unknown\"].filename == \"unknown\"\n        data[\"unknown\"].file.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(b\"data\") as file_handle:\n        async with client.post(\"/\", data=[file_handle]) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_IO_WITH_PARAMS(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data[\"test\"] == \"true\"\n        assert isinstance(data[\"unknown\"], web.FileField)\n        assert data[\"unknown\"].content_type == \"application/octet-stream\"\n        assert data[\"unknown\"].filename == \"unknown\"\n        assert data[\"unknown\"].file.read() == b\"data\"\n        data[\"unknown\"].file.close()\n        assert data.getall(\"q\") == [\"t1\", \"t2\"]\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with io.BytesIO(b\"data\") as file_handle:\n        async with client.post(\n            \"/\",\n            data=((\"test\", \"true\"), MultiDict([(\"q\", \"t1\"), (\"q\", \"t2\")]), file_handle),\n        ) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_FILES_WITH_DATA(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data[\"test\"] == \"true\"\n        assert isinstance(data[\"some\"], web.FileField)\n        assert data[\"some\"].content_type in [\n            \"text/x-python\",\n            \"text/plain\",\n            \"application/octet-stream\",\n        ]\n        assert data[\"some\"].filename == fname.name\n        with fname.open(\"rb\") as f:\n            assert data[\"some\"].file.read() == f.read()\n            data[\"some\"].file.close()\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        async with client.post(\"/\", data={\"test\": \"true\", \"some\": f}) as resp:\n            assert 200 == resp.status\n\n\nasync def test_POST_STREAM_DATA(\n    aiohttp_client: AiohttpClient, fname: pathlib.Path\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/octet-stream\"\n        content = await request.read()\n        with fname.open(\"rb\") as f:\n            expected = f.read()\n            assert request.content_length == len(expected)\n            assert content == expected\n\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with fname.open(\"rb\") as f:\n        data_size = len(f.read())\n\n    async def gen(fname: pathlib.Path) -> AsyncIterator[bytes]:\n        with fname.open(\"rb\") as f:\n            data = f.read(100)\n            while data:\n                yield data\n                data = f.read(100)\n\n    async with client.post(\n        \"/\", data=gen(fname), headers={\"Content-Length\": str(data_size)}\n    ) as resp:\n        assert 200 == resp.status\n\n\nasync def test_json(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/json\"\n        data = await request.json()\n        return web.Response(body=aiohttp.JsonPayload(data))\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.post(\"/\", json={\"some\": \"data\"})\n    assert 200 == resp.status\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n    with pytest.raises(ValueError):\n        await client.post(\"/\", data=\"some data\", json={\"some\": \"data\"})\n\n\nasync def test_json_custom(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.content_type == \"application/json\"\n        data = await request.json()\n        return web.Response(body=aiohttp.JsonPayload(data))\n\n    used = False\n\n    def dumps(obj: Any) -> str:\n        nonlocal used\n        used = True\n        return json.dumps(obj)\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app, json_serialize=dumps)\n\n    resp = await client.post(\"/\", json={\"some\": \"data\"})\n    assert 200 == resp.status\n    assert used\n    content = await resp.json()\n    assert content == {\"some\": \"data\"}\n    resp.close()\n\n    with pytest.raises(ValueError):\n        await client.post(\"/\", data=\"some data\", json={\"some\": \"data\"})\n\n\nasync def test_expect_continue(aiohttp_client: AiohttpClient) -> None:\n    expect_called = False\n\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.post()\n        assert data == {\"some\": \"data\"}\n        return web.Response()\n\n    async def expect_handler(request: web.Request) -> None:\n        nonlocal expect_called\n        expect = request.headers[hdrs.EXPECT]\n        assert expect.lower() == \"100-continue\"\n        assert request.transport is not None\n        request.transport.write(b\"HTTP/1.1 100 Continue\\r\\n\\r\\n\")\n        expect_called = True\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler, expect_handler=expect_handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\"/\", data={\"some\": \"data\"}, expect100=True) as resp:\n        assert 200 == resp.status\n    assert expect_called\n\n\nasync def test_encoding_deflate(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        resp.enable_compression(web.ContentCoding.deflate)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_deflate_nochunk(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_compression(web.ContentCoding.deflate)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_gzip(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        resp.enable_compression(web.ContentCoding.gzip)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_encoding_gzip_write_by_chunks(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        resp.enable_compression(web.ContentCoding.gzip)\n        await resp.prepare(request)\n        await resp.write(b\"0\")\n        await resp.write(b\"0\")\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"00\"\n    resp.close()\n\n\nasync def test_encoding_gzip_nochunk(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_compression(web.ContentCoding.gzip)\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_bad_payload_compression(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.headers[\"Content-Encoding\"] = \"gzip\"\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_bad_payload_chunked_encoding(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse()\n        resp.force_close()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write(b\"9\\r\\n\\r\\n\")\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_no_payload_304_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test a 304 response with no payload with chunked set should have it removed.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=304)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 304\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING not in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_head_request_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test a head response with chunked set should have it removed.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=200)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_head(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.head(\"/\")\n    assert resp.status == 200\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING not in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_no_payload_200_with_chunked_encoding(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    \"\"\"Test chunked is preserved on a 200 response with no payload.\"\"\"\n\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(status=200)\n        resp.enable_chunked_encoding()\n        resp._length_check = False\n        resp.headers[\"Transfer-Encoding\"] = \"chunked\"\n        writer = await resp.prepare(request)\n        assert writer is not None\n        await writer.write_eof()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert resp.status == 200\n    assert hdrs.CONTENT_LENGTH not in resp.headers\n    assert hdrs.TRANSFER_ENCODING in resp.headers\n    await resp.read()\n\n    resp.close()\n\n\nasync def test_bad_payload_content_length(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.headers[\"Content-Length\"] = \"10000\"\n        resp.force_close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n\n    resp.close()\n\n\nasync def test_payload_content_length_by_chunks(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"2\"})\n        await resp.prepare(request)\n        await resp.write(b\"answer\")\n        await resp.write(b\"two\")\n        assert request.transport is not None\n        request.transport.close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    data = await resp.read()\n    assert data == b\"an\"\n    resp.close()\n\n\nasync def test_chunked(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        resp = web.Response(text=\"text\")\n        resp.enable_chunked_encoding()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    assert 200 == resp.status\n    assert resp.headers[\"Transfer-Encoding\"] == \"chunked\"\n    txt = await resp.text()\n    assert txt == \"text\"\n    resp.close()\n\n\nasync def test_shortcuts(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    app = web.Application()\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        app.router.add_route(meth.upper(), \"/\", handler)\n    client = await aiohttp_client(app)\n\n    for meth in (\"get\", \"post\", \"put\", \"delete\", \"head\", \"patch\", \"options\"):\n        coro = getattr(client.session, meth)\n        resp = await coro(client.make_url(\"/\"))\n\n        assert resp.status == 200\n        assert len(resp.history) == 0\n\n        content1 = await resp.read()\n        content2 = await resp.read()\n        assert content1 == content2\n        content = await resp.text()\n\n        if meth == \"head\":\n            assert b\"\" == content1\n        else:\n            assert meth.upper() == content\n\n\nasync def test_cookies(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test1\", \"test3\"}\n        assert request.cookies[\"test1\"] == \"123\"\n        assert request.cookies[\"test3\"] == \"456\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test1\": \"123\", \"test2\": c})\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_per_request(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test1\", \"test3\", \"test4\", \"test6\"}\n        assert request.cookies[\"test1\"] == \"123\"\n        assert request.cookies[\"test3\"] == \"456\"\n        assert request.cookies[\"test4\"] == \"789\"\n        assert request.cookies[\"test6\"] == \"abc\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test1\": \"123\", \"test2\": c})\n\n    rc: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    rc.set(\"test6\", \"abc\", \"abc\")\n\n    cookies: Dict[str, Union[str, \"http.cookies.Morsel[str]\"]]\n    cookies = {\"test4\": \"789\", \"test5\": rc}\n    async with client.get(\"/\", cookies=cookies) as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_redirect(aiohttp_client: AiohttpClient) -> None:\n    async def redirect1(request: web.Request) -> web.Response:\n        ret = web.Response(status=301, headers={\"Location\": \"/redirect2\"})\n        ret.set_cookie(\"c\", \"1\")\n        return ret\n\n    async def redirect2(request: web.Request) -> web.Response:\n        ret = web.Response(status=301, headers={\"Location\": \"/\"})\n        ret.set_cookie(\"c\", \"2\")\n        return ret\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"c\"}\n        assert request.cookies[\"c\"] == \"2\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/redirect1\", redirect1)\n    app.router.add_get(\"/redirect2\", redirect2)\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/redirect1\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_cookies_on_empty_session_jar(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert \"custom-cookie\" in request.cookies\n        assert request.cookies[\"custom-cookie\"] == \"abc\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies=None)\n\n    async with client.get(\"/\", cookies={\"custom-cookie\": \"abc\"}) as resp:\n        assert 200 == resp.status\n\n\nasync def test_morsel_with_attributes(aiohttp_client: AiohttpClient) -> None:\n    # A comment from original test:\n    #\n    # No cookie attribute should pass here\n    # they are only used as filters\n    # whether to send particular cookie or not.\n    # E.g. if cookie expires it just becomes thrown away.\n    # Server who sent the cookie with some attributes\n    # already knows them, no need to send this back again and again\n\n    async def handler(request: web.Request) -> web.Response:\n        assert request.cookies.keys() == {\"test3\"}\n        assert request.cookies[\"test3\"] == \"456\"\n        return web.Response()\n\n    c: \"http.cookies.Morsel[str]\" = http.cookies.Morsel()\n    c.set(\"test3\", \"456\", \"456\")\n    c[\"httponly\"] = True\n    c[\"secure\"] = True\n    c[\"max-age\"] = 1000\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app, cookies={\"test2\": c})\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_set_cookies(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"ISAWPLB{A7F52349-3531-4DA9-8776-F74BC6F4F1BB}=\"\n            \"{925EC0B8-CB17-4BEB-8A35-1033813B0523}; \"\n            \"HttpOnly; Path=/\",\n        )\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with mock.patch(\"aiohttp.client_reqrep.client_logger\") as m_log:\n        async with client.get(\"/\") as resp:\n            assert 200 == resp.status\n            cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\"}\n\n        m_log.warning.assert_called_with(\"Can not load response cookies: %s\", mock.ANY)\n\n\nasync def test_set_cookies_expired(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"c3=cookie3; HttpOnly; Path=/ Expires=Tue, 1 Jan 1980 12:00:00 GMT; \",\n        )\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        cookie_names = {c.key for c in client.session.cookie_jar}\n    assert cookie_names == {\"c1\", \"c2\"}\n\n\nasync def test_set_cookies_max_age(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.set_cookie(\"c1\", \"cookie1\")\n        ret.set_cookie(\"c2\", \"cookie2\")\n        ret.headers.add(\"Set-Cookie\", \"c3=cookie3; HttpOnly; Path=/ Max-Age=1; \")\n        return ret\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\", \"c3\"}\n        await asyncio.sleep(2)\n        cookie_names = {c.key for c in client.session.cookie_jar}\n        assert cookie_names == {\"c1\", \"c2\"}\n\n\nasync def test_set_cookies_max_age_overflow(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        ret = web.Response()\n        ret.headers.add(\n            \"Set-Cookie\",\n            \"overflow=overflow; HttpOnly; Path=/ Max-Age=\" + str(overflow) + \"; \",\n        )\n        return ret\n\n    overflow = int(\n        datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()\n    )\n    empty = None\n    try:\n        empty = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(\n            seconds=overflow\n        )\n    except OverflowError as ex:\n        assert isinstance(ex, OverflowError)\n    assert not isinstance(empty, datetime.datetime)\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert 200 == resp.status\n        for cookie in client.session.cookie_jar:\n            assert cookie.key == \"overflow\"\n            assert int(cookie[\"max-age\"]) == int(overflow)\n\n\nasync def test_request_conn_error() -> None:\n    client = aiohttp.ClientSession()\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"http://0.0.0.0:1\")\n    await client.close()\n\n\n@pytest.mark.xfail\nasync def test_broken_connection(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.transport is not None\n        request.transport.close()\n        return web.Response(text=\"answer\" * 1000)\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_broken_connection_2(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.StreamResponse:\n        resp = web.StreamResponse(headers={\"content-length\": \"1000\"})\n        await resp.prepare(request)\n        await resp.write(b\"answer\")\n        assert request.transport is not None\n        request.transport.close()\n        return resp\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/\")\n    with pytest.raises(aiohttp.ClientPayloadError):\n        await resp.read()\n    resp.close()\n\n\nasync def test_custom_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.headers[\"x-api-key\"] == \"foo\"\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n    client = await aiohttp_client(app)\n\n    async with client.post(\n        \"/\", headers={\"Content-Type\": \"application/json\", \"x-api-key\": \"foo\"}\n    ) as resp:\n        assert resp.status == 200\n\n\nasync def test_redirect_to_absolute_url(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(text=request.method)\n\n    async def redirect(request: web.Request) -> NoReturn:\n        raise web.HTTPFound(location=client.make_url(\"/\"))\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    app.router.add_get(\"/redirect\", redirect)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/redirect\") as resp:\n        assert 200 == resp.status\n\n\nasync def test_redirect_without_location_header(aiohttp_client: AiohttpClient) -> None:\n    body = b\"redirect\"\n\n    async def handler_redirect(request: web.Request) -> web.Response:\n        return web.Response(status=301, body=body)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/redirect\", handler_redirect)\n    client = await aiohttp_client(app)\n\n    resp = await client.get(\"/redirect\")\n    data = await resp.read()\n    assert data == body\n\n\nINVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW = (\n    # yarl.URL.__new__ raises ValueError\n    (\"http://:/\", \"http://:/\"),\n    (\"http://example.org:non_int_port/\", \"http://example.org:non_int_port/\"),\n)\n\nINVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN = (\n    # # yarl.URL.origin raises ValueError\n    (\"http:/\", \"http:///\"),\n    (\"http:/example.com\", \"http:///example.com\"),\n    (\"http:///example.com\", \"http:///example.com\"),\n)\n\nNON_HTTP_URL_WITH_ERROR_MESSAGE = (\n    (\"call:+380123456789\", r\"call:\\+380123456789\"),\n    (\"skype:handle\", \"skype:handle\"),\n    (\"slack://instance/room\", \"slack://instance/room\"),\n    (\"steam:code\", \"steam:code\"),\n    (\"twitter://handle\", \"twitter://handle\"),\n    (\"bluesky://profile/d:i:d\", \"bluesky://profile/d:i:d\"),\n)\n\n\n@pytest.mark.parametrize(\n    (\"url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, InvalidUrlClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n        ),\n        *(\n            (url, message, NonHttpUrlClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_and_non_http_url(\n    url: str, error_message_url: str, expected_exception_class: Type[Exception]\n) -> None:\n    async with aiohttp.ClientSession() as http_session:\n        with pytest.raises(\n            expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n        ):\n            await http_session.get(url)\n\n\n@pytest.mark.parametrize(\n    (\"invalid_redirect_url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlRedirectClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n            + INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, NonHttpUrlRedirectClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_redirect_url(\n    aiohttp_client: AiohttpClient,\n    invalid_redirect_url: str,\n    error_message_url: str,\n    expected_exception_class: Type[Exception],\n) -> None:\n    headers = {hdrs.LOCATION: invalid_redirect_url}\n\n    async def generate_redirecting_response(request: web.Request) -> web.Response:\n        return web.Response(status=301, headers=headers)\n\n    app = web.Application()\n    app.router.add_get(\"/redirect\", generate_redirecting_response)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n    ):\n        await client.get(\"/redirect\")\n\n\n@pytest.mark.parametrize(\n    (\"invalid_redirect_url\", \"error_message_url\", \"expected_exception_class\"),\n    (\n        *(\n            (url, message, InvalidUrlRedirectClientError)\n            for (url, message) in INVALID_URL_WITH_ERROR_MESSAGE_YARL_ORIGIN\n            + INVALID_URL_WITH_ERROR_MESSAGE_YARL_NEW\n        ),\n        *(\n            (url, message, NonHttpUrlRedirectClientError)\n            for (url, message) in NON_HTTP_URL_WITH_ERROR_MESSAGE\n        ),\n    ),\n)\nasync def test_invalid_redirect_url_multiple_redirects(\n    aiohttp_client: AiohttpClient,\n    invalid_redirect_url: str,\n    error_message_url: str,\n    expected_exception_class: Type[Exception],\n) -> None:\n    app = web.Application()\n\n    for path, location in [\n        (\"/redirect\", \"/redirect1\"),\n        (\"/redirect1\", \"/redirect2\"),\n        (\"/redirect2\", invalid_redirect_url),\n    ]:\n\n        async def generate_redirecting_response(request: web.Request) -> web.Response:\n            return web.Response(status=301, headers={hdrs.LOCATION: location})\n\n        app.router.add_get(path, generate_redirecting_response)\n\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        expected_exception_class, match=rf\"^{error_message_url}( - [A-Za-z ]+)?\"\n    ):\n        await client.get(\"/redirect\")\n\n\n@pytest.mark.parametrize(\n    (\"status\", \"expected_ok\"),\n    (\n        (200, True),\n        (201, True),\n        (301, True),\n        (400, False),\n        (403, False),\n        (500, False),\n    ),\n)\nasync def test_ok_from_status(\n    aiohttp_client: AiohttpClient, status: int, expected_ok: bool\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=status, body=b\"\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/endpoint\", handler)\n    client = await aiohttp_client(app, raise_for_status=False)\n    async with client.get(\"/endpoint\") as resp:\n        assert resp.ok is expected_ok\n\n\nasync def test_raise_for_status(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, raise_for_status=True)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_raise_for_status_per_request(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app)\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\", raise_for_status=True)\n\n\nasync def test_raise_for_status_disable_per_request(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n    client = await aiohttp_client(app, raise_for_status=True)\n\n    async with client.get(\"/\", raise_for_status=False) as resp:\n        assert 400 == resp.status\n\n\nasync def test_request_raise_for_status_default(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.request(\"GET\", server.make_url(\"/\")) as resp:\n        assert resp.status == 400\n\n\nasync def test_request_raise_for_status_disabled(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n    url = server.make_url(\"/\")\n\n    async with aiohttp.request(\"GET\", url, raise_for_status=False) as resp:\n        assert resp.status == 400\n\n\nasync def test_request_raise_for_status_enabled(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n    url = server.make_url(\"/\")\n\n    with pytest.raises(aiohttp.ClientResponseError):\n        async with aiohttp.request(\"GET\", url, raise_for_status=True):\n            assert False, \"never executed\"  # pragma: no cover\n\n\nasync def test_session_raise_for_status_coro(aiohttp_client: AiohttpClient) -> None:\n    async def handle(request: web.Request) -> web.Response:\n        return web.Response(text=\"ok\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handle)\n\n    raise_for_status_called = 0\n\n    async def custom_r4s(response: aiohttp.ClientResponse) -> None:\n        nonlocal raise_for_status_called\n        raise_for_status_called += 1\n        assert response.status == 200\n        assert response.request_info.method == \"GET\"\n\n    client = await aiohttp_client(app, raise_for_status=custom_r4s)\n    await client.get(\"/\")\n    assert raise_for_status_called == 1\n    await client.get(\"/\", raise_for_status=True)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n    await client.get(\"/\", raise_for_status=False)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n\n\nasync def test_request_raise_for_status_coro(aiohttp_client: AiohttpClient) -> None:\n    async def handle(request: web.Request) -> web.Response:\n        return web.Response(text=\"ok\")\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handle)\n\n    raise_for_status_called = 0\n\n    async def custom_r4s(response: aiohttp.ClientResponse) -> None:\n        nonlocal raise_for_status_called\n        raise_for_status_called += 1\n        assert response.status == 200\n        assert response.request_info.method == \"GET\"\n\n    client = await aiohttp_client(app)\n    await client.get(\"/\", raise_for_status=custom_r4s)\n    assert raise_for_status_called == 1\n    await client.get(\"/\", raise_for_status=True)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n    await client.get(\"/\", raise_for_status=False)\n    assert raise_for_status_called == 1  # custom_r4s not called again\n\n\nasync def test_invalid_idna() -> None:\n    session = aiohttp.ClientSession()\n    try:\n        with pytest.raises(aiohttp.InvalidURL):\n            await session.get(\"http://\\u2061owhefopw.com\")\n    finally:\n        await session.close()\n\n\nasync def test_creds_in_auth_and_url() -> None:\n    session = aiohttp.ClientSession()\n    try:\n        with pytest.raises(ValueError):\n            await session.get(\n                \"http://user:pass@example.com\", auth=aiohttp.BasicAuth(\"user2\", \"pass2\")\n            )\n    finally:\n        await session.close()\n\n\n@pytest.fixture\ndef create_server_for_url_and_handler(\n    aiohttp_server: AiohttpServer, tls_certificate_authority: trustme.CA\n) -> Callable[[URL, Handler], Awaitable[TestServer]]:\n    def create(url: URL, srv: Handler) -> Awaitable[TestServer]:\n        app = web.Application()\n        app.router.add_route(\"GET\", url.path, srv)\n\n        if url.scheme == \"https\":\n            assert url.host\n            cert = tls_certificate_authority.issue_cert(\n                url.host, \"localhost\", \"127.0.0.1\"\n            )\n            ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n            cert.configure_cert(ssl_ctx)\n            return aiohttp_server(app, ssl=ssl_ctx)\n        return aiohttp_server(app)\n\n    return create\n\n\n@pytest.mark.parametrize(\n    [\"url_from_s\", \"url_to_s\", \"is_drop_header_expected\"],\n    [\n        [\n            \"http://host1.com/path1\",\n            \"http://host2.com/path2\",\n            True,\n        ],\n        [\"http://host1.com/path1\", \"https://host1.com/path1\", False],\n        [\"https://host1.com/path1\", \"http://host1.com/path2\", True],\n    ],\n    ids=(\n        \"entirely different hosts\",\n        \"http -> https\",\n        \"https -> http\",\n    ),\n)\nasync def test_drop_auth_on_redirect_to_other_host(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n    url_from_s: str,\n    url_to_s: str,\n    is_drop_header_expected: bool,\n) -> None:\n    url_from, url_to = URL(url_from_s), URL(url_to_s)\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        if is_drop_header_expected:\n            assert \"Authorization\" not in request.headers, \"Header wasn't dropped\"\n        else:\n            assert \"Authorization\" in request.headers, \"Header was dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(connector=connector) as client:\n        resp = await client.get(\n            url_from,\n            auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n        )\n        assert resp.status == 200\n        resp = await client.get(\n            url_from,\n            headers={\"Authorization\": \"Basic dXNlcjpwYXNz\"},\n        )\n        assert resp.status == 200\n\n\nasync def test_auth_persist_on_redirect_to_other_host_with_global_auth(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n) -> None:\n    url_from = URL(\"http://host1.com/path1\")\n    url_to = URL(\"http://host2.com/path2\")\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        assert \"Authorization\" in request.headers, \"Header was dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(\n        connector=connector, auth=aiohttp.BasicAuth(\"user\", \"pass\")\n    ) as client:\n        resp = await client.get(url_from)\n        assert resp.status == 200\n\n\nasync def test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url(\n    create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n) -> None:\n    url_from = URL(\"http://host1.com/path1\")\n    url_to = URL(\"http://host2.com/path2\")\n\n    async def srv_from(request: web.Request) -> NoReturn:\n        assert request.host == url_from.host\n        assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n        raise web.HTTPFound(url_to)\n\n    async def srv_to(request: web.Request) -> web.Response:\n        assert request.host == url_to.host\n        assert \"Authorization\" not in request.headers, \"Header was not dropped\"\n        return web.Response()\n\n    server_from = await create_server_for_url_and_handler(url_from, srv_from)\n    server_to = await create_server_for_url_and_handler(url_to, srv_to)\n\n    assert (\n        url_from.host != url_to.host or server_from.scheme != server_to.scheme\n    ), \"Invalid test case, host or scheme must differ\"\n\n    protocol_port_map = {\n        \"http\": 80,\n        \"https\": 443,\n    }\n    etc_hosts = {\n        (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n        (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n    }\n\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            server = etc_hosts[(host, port)]\n            assert server.port is not None\n\n            return [\n                {\n                    \"hostname\": host,\n                    \"host\": server.host,\n                    \"port\": server.port,\n                    \"family\": socket.AF_INET,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST,\n                }\n            ]\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n\n    async with aiohttp.ClientSession(\n        connector=connector,\n        base_url=\"http://host1.com\",\n        auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n    ) as client:\n        resp = await client.get(\"/path1\")\n        assert resp.status == 200\n\n\nasync def test_async_with_session() -> None:\n    async with aiohttp.ClientSession() as session:\n        pass\n\n    assert session.closed\n\n\nasync def test_session_close_awaitable() -> None:\n    session = aiohttp.ClientSession()\n    await session.close()\n\n    assert session.closed\n\n\nasync def test_close_resp_on_error_async_with_session(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.ClientSession() as session:\n        with pytest.raises(RuntimeError):\n            async with session.get(server.make_url(\"/\")) as resp:\n                resp.content.set_exception(RuntimeError())\n                await resp.read()\n\n        assert session._connector is not None\n        assert len(session._connector._conns) == 0\n\n\nasync def test_release_resp_on_normal_exit_from_cm(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.ClientSession() as session:\n        async with session.get(server.make_url(\"/\")) as resp:\n            await resp.read()\n\n        assert session._connector is not None\n        assert len(session._connector._conns) == 1\n\n\nasync def test_non_close_detached_session_on_error_cm(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = web.StreamResponse(headers={\"content-length\": \"100\"})\n        await resp.prepare(request)\n        await asyncio.sleep(0.1)\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    session = aiohttp.ClientSession()\n    cm = session.get(server.make_url(\"/\"))\n    assert not session.closed\n    with pytest.raises(RuntimeError):\n        async with cm as resp:\n            resp.content.set_exception(RuntimeError())\n            await resp.read()\n    assert not session.closed\n\n\nasync def test_close_detached_session_on_non_existing_addr() -> None:\n    class FakeResolver(AbstractResolver):\n        async def resolve(\n            self,\n            host: str,\n            port: int = 0,\n            family: socket.AddressFamily = socket.AF_INET,\n        ) -> List[ResolveResult]:\n            return []\n\n        async def close(self) -> None:\n            \"\"\"Dummy\"\"\"\n\n    connector = aiohttp.TCPConnector(resolver=FakeResolver())\n\n    session = aiohttp.ClientSession(connector=connector)\n\n    async with session:\n        cm = session.get(\"http://non-existing.example.com\")\n        assert not session.closed\n        with pytest.raises(Exception):\n            await cm\n\n    assert session.closed\n\n\nasync def test_aiohttp_request_context_manager(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    async with aiohttp.request(\"GET\", server.make_url(\"/\")) as resp:\n        await resp.read()\n        assert resp.status == 200\n\n\nasync def test_aiohttp_request_ctx_manager_close_sess_on_error(\n    ssl_ctx: ssl.SSLContext, aiohttp_server: AiohttpServer\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n\n    cm = aiohttp.request(\"GET\", server.make_url(\"/\"))\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        async with cm:\n            pass\n\n    assert cm._session.closed\n\n\nasync def test_aiohttp_request_ctx_manager_not_found() -> None:\n    with pytest.raises(aiohttp.ClientConnectionError):\n        async with aiohttp.request(\"GET\", \"http://wrong-dns-name.com\"):\n            assert False, \"never executed\"  # pragma: no cover\n\n\nasync def test_aiohttp_request_coroutine(aiohttp_server: AiohttpServer) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    server = await aiohttp_server(app)\n\n    not_an_awaitable = aiohttp.request(\"GET\", server.make_url(\"/\"))\n    with pytest.raises(\n        TypeError,\n        match=\"^object _SessionRequestContextManager \"\n        \"can't be used in 'await' expression$\",\n    ):\n        await not_an_awaitable  # type: ignore[misc]\n\n    await not_an_awaitable._coro  # coroutine 'ClientSession._request' was never awaited\n    await server.close()\n\n\nasync def test_yield_from_in_session_request(aiohttp_client: AiohttpClient) -> None:\n    # a test for backward compatibility with yield from syntax\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n\nasync def test_close_context_manager(aiohttp_client: AiohttpClient) -> None:\n    # a test for backward compatibility with yield from syntax\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    ctx = client.get(\"/\")\n    ctx.close()\n    assert not ctx._coro.cr_running\n\n\nasync def test_session_auth(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n\n    r = await client.get(\"/\")\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"Authorization\"] == \"Basic bG9naW46cGFzcw==\"\n\n\nasync def test_session_auth_override(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n\n    r = await client.get(\"/\", auth=aiohttp.BasicAuth(\"other_login\", \"pass\"))\n    assert r.status == 200\n    content = await r.json()\n    val = content[\"headers\"][\"Authorization\"]\n    assert val == \"Basic b3RoZXJfbG9naW46cGFzcw==\"\n\n\nasync def test_session_auth_header_conflict(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, auth=aiohttp.BasicAuth(\"login\", \"pass\"))\n    headers = {\"Authorization\": \"Basic b3RoZXJfbG9naW46cGFzcw==\"}\n    with pytest.raises(ValueError):\n        await client.get(\"/\", headers=headers)\n\n\nasync def test_session_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app, headers={\"X-Real-IP\": \"192.168.0.1\"})\n\n    r = await client.get(\"/\")\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"X-Real-IP\"] == \"192.168.0.1\"\n\n\nasync def test_session_headers_merge(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.json_response({\"headers\": dict(request.headers)})\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(\n        app, headers=[(\"X-Real-IP\", \"192.168.0.1\"), (\"X-Sent-By\", \"requests\")]\n    )\n\n    r = await client.get(\"/\", headers={\"X-Sent-By\": \"aiohttp\"})\n    assert r.status == 200\n    content = await r.json()\n    assert content[\"headers\"][\"X-Real-IP\"] == \"192.168.0.1\"\n    assert content[\"headers\"][\"X-Sent-By\"] == \"aiohttp\"\n\n\nasync def test_multidict_headers(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert await request.read() == data\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_post(\"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    data = b\"sample data\"\n\n    async with client.post(\n        \"/\", data=data, headers=MultiDict({\"Content-Length\": str(len(data))})\n    ) as r:\n        assert r.status == 200\n\n\nasync def test_request_conn_closed(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        assert request.transport is not None\n        request.transport.close()\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ServerDisconnectedError) as excinfo:\n        resp = await client.get(\"/\")\n        await resp.read()\n\n    assert str(excinfo.value) != \"\"\n\n\nasync def test_dont_close_explicit_connector(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    client = await aiohttp_client(app)\n    r = await client.get(\"/\")\n    await r.read()\n\n    assert client.session.connector is not None\n    assert 1 == len(client.session.connector._conns)\n\n\nasync def test_server_close_keepalive_connection() -> None:\n    loop = asyncio.get_event_loop()\n\n    class Proto(asyncio.Protocol):\n        def connection_made(self, transport: asyncio.BaseTransport) -> None:\n            assert isinstance(transport, asyncio.Transport)\n            self.transp: Optional[asyncio.Transport] = transport\n            self.data = b\"\"\n\n        def data_received(self, data: bytes) -> None:\n            self.data += data\n            assert data.endswith(b\"\\r\\n\\r\\n\")\n            assert self.transp is not None\n            self.transp.write(\n                b\"HTTP/1.1 200 OK\\r\\n\"\n                b\"CONTENT-LENGTH: 2\\r\\n\"\n                b\"CONNECTION: close\\r\\n\"\n                b\"\\r\\n\"\n                b\"ok\"\n            )\n            self.transp.close()\n\n        def connection_lost(self, exc: Optional[BaseException]) -> None:\n            self.transp = None\n\n    server = await loop.create_server(Proto, \"127.0.0.1\", unused_port())\n\n    addr = server.sockets[0].getsockname()\n\n    connector = aiohttp.TCPConnector(limit=1)\n    session = aiohttp.ClientSession(connector=connector)\n\n    url = \"http://{}:{}/\".format(*addr)\n    for i in range(2):\n        r = await session.request(\"GET\", url)\n        await r.read()\n        assert 0 == len(connector._conns)\n    await session.close()\n    await connector.close()\n    server.close()\n    await server.wait_closed()\n\n\nasync def test_handle_keepalive_on_closed_connection() -> None:\n    loop = asyncio.get_event_loop()\n\n    class Proto(asyncio.Protocol):\n        def connection_made(self, transport: asyncio.BaseTransport) -> None:\n            assert isinstance(transport, asyncio.Transport)\n            self.transp: Optional[asyncio.Transport] = transport\n            self.data = b\"\"\n\n        def data_received(self, data: bytes) -> None:\n            self.data += data\n            assert data.endswith(b\"\\r\\n\\r\\n\")\n            assert self.transp is not None\n            self.transp.write(b\"HTTP/1.1 200 OK\\r\\nCONTENT-LENGTH: 2\\r\\n\\r\\nok\")\n            self.transp.close()\n\n        def connection_lost(self, exc: Optional[BaseException]) -> None:\n            self.transp = None\n\n    server = await loop.create_server(Proto, \"127.0.0.1\", unused_port())\n\n    addr = server.sockets[0].getsockname()\n\n    async with aiohttp.TCPConnector(limit=1) as connector:\n        async with aiohttp.ClientSession(connector=connector) as session:\n            url = \"http://{}:{}/\".format(*addr)\n\n            r = await session.request(\"GET\", url)\n            await r.read()\n            assert 1 == len(connector._conns)\n            closed_conn = next(iter(connector._conns.values()))\n\n            await session.request(\"GET\", url)\n            assert 1 == len(connector._conns)\n            new_conn = next(iter(connector._conns.values()))\n            assert closed_conn is not new_conn\n\n    server.close()\n    await server.wait_closed()\n\n\nasync def test_error_in_performing_request(\n    ssl_ctx: ssl.SSLContext,\n    aiohttp_client: AiohttpClient,\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        assert False\n\n    def exception_handler(loop: object, context: object) -> None:\n        \"\"\"Skip log messages about destroyed but pending tasks\"\"\"\n\n    loop = asyncio.get_event_loop()\n    loop.set_exception_handler(exception_handler)\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    server = await aiohttp_server(app, ssl=ssl_ctx)\n\n    conn = aiohttp.TCPConnector(limit=1)\n    client = await aiohttp_client(server, connector=conn)\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"/\")\n\n    # second try should not hang\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await client.get(\"/\")\n\n\nasync def test_await_after_cancelling(aiohttp_client: AiohttpClient) -> None:\n    loop = asyncio.get_event_loop()\n\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_route(\"GET\", \"/\", handler)\n\n    client = await aiohttp_client(app)\n\n    fut1 = loop.create_future()\n    fut2 = loop.create_future()\n\n    async def fetch1() -> None:\n        resp = await client.get(\"/\")\n        assert resp.status == 200\n        fut1.set_result(None)\n        with pytest.raises(asyncio.CancelledError):\n            await fut2\n        resp.release()\n\n    async def fetch2() -> None:\n        await fut1\n        resp = await client.get(\"/\")\n        assert resp.status == 200\n\n    async def canceller() -> None:\n        await fut1\n        fut2.cancel()\n\n    await asyncio.gather(fetch1(), fetch2(), canceller())\n\n\nasync def test_async_payload_generator(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        assert data == b\"1234567890\" * 100\n        return web.Response()\n\n    app = web.Application()\n    app.add_routes([web.post(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async def gen() -> AsyncIterator[bytes]:\n        for i in range(100):\n            yield b\"1234567890\"\n\n    async with client.post(\"/\", data=gen()) as resp:\n        assert resp.status == 200\n\n\nasync def test_read_from_closed_response(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.read()\n\n\nasync def test_read_from_closed_response2(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n        await resp.read()\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.read()\n\n\nasync def test_read_from_closed_content(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"data\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with client.get(\"/\") as resp:\n        assert resp.status == 200\n\n    with pytest.raises(aiohttp.ClientConnectionError):\n        await resp.content.readline()\n\n\nasync def test_read_timeout(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(aiohttp.ServerTimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_socket_timeout(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(SocketTimeoutError):\n        await client.get(\"/\")\n\n\nasync def test_read_timeout_closes_connection(aiohttp_client: AiohttpClient) -> None:\n    request_count = 0\n\n    async def handler(request: web.Request) -> web.Response:\n        nonlocal request_count\n        request_count += 1\n        if request_count < 3:\n            await asyncio.sleep(0.5)\n        return web.Response(body=f\"request:{request_count}\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(total=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n    # Make sure its really closed\n    assert client.session.connector is not None\n    assert not client.session.connector._conns\n\n    with pytest.raises(asyncio.TimeoutError):\n        await client.get(\"/\")\n\n    # Make sure its really closed\n    assert not client.session.connector._conns\n    result = await client.get(\"/\")\n    assert await result.read() == b\"request:3\"\n\n    # Make sure its not closed\n    assert client.session.connector._conns\n\n\nasync def test_read_timeout_on_prepared_response(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> NoReturn:\n        resp = aiohttp.web.StreamResponse()\n        await resp.prepare(request)\n        await asyncio.sleep(5)\n        assert False\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    timeout = aiohttp.ClientTimeout(sock_read=0.1)\n    client = await aiohttp_client(app, timeout=timeout)\n\n    with pytest.raises(aiohttp.ServerTimeoutError):\n        async with await client.get(\"/\") as resp:\n            await resp.read()\n\n\nasync def test_timeout_with_full_buffer(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        \"\"\"Server response that never ends and always has more data available.\"\"\"\n        resp = web.StreamResponse()\n        await resp.prepare(request)\n        while True:\n            await resp.write(b\"1\" * 1000)\n            await asyncio.sleep(0.01)\n\n    async def request(client: TestClient[web.Request]) -> None:\n        timeout = aiohttp.ClientTimeout(total=0.5)\n        async with await client.get(\"/\", timeout=timeout) as resp:\n            with pytest.raises(asyncio.TimeoutError):\n                async for data in resp.content.iter_chunked(1):\n                    await asyncio.sleep(0.01)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    # wait_for() used just to ensure that a failing test doesn't hang.\n    await asyncio.wait_for(request(client), 1)\n\n\nasync def test_read_bufsize_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1234567\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, read_bufsize=2)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.content.get_read_buffer_limits() == (2, 4)\n\n\nasync def test_read_bufsize_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1234567\")\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", read_bufsize=4) as resp:\n        assert resp.content.get_read_buffer_limits() == (4, 8)\n\n\nasync def test_http_empty_data_text(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        data = await request.read()\n        ret = \"ok\" if data == b\"\" else \"fail\"\n        resp = web.Response(text=ret)\n        resp.headers[\"Content-Type\"] = request.headers[\"Content-Type\"]\n        return resp\n\n    app = web.Application()\n    app.add_routes([web.post(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.post(\"/\", data=\"\") as resp:\n        assert resp.status == 200\n        assert await resp.text() == \"ok\"\n        assert resp.headers[\"Content-Type\"] == \"text/plain; charset=utf-8\"\n\n\nasync def test_max_field_size_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8190})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8190\n\n\nasync def test_max_field_size_session_default_fail(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_max_field_size_session_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, max_field_size=8191)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8191\n\n\nasync def test_max_field_size_request_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(headers={\"Custom\": \"x\" * 8191})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", max_field_size=8191) as resp:\n        assert resp.headers[\"Custom\"] == \"x\" * 8191\n\n\nasync def test_max_line_size_session_default(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8190)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.reason == \"x\" * 8190\n\n\nasync def test_max_line_size_session_default_fail(\n    aiohttp_client: AiohttpClient,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8192)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n    with pytest.raises(aiohttp.ClientResponseError):\n        await client.get(\"/\")\n\n\nasync def test_max_line_size_session_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8191)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app, max_line_size=8191)\n\n    async with await client.get(\"/\") as resp:\n        assert resp.reason == \"x\" * 8191\n\n\nasync def test_max_line_size_request_explicit(aiohttp_client: AiohttpClient) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(status=200, reason=\"x\" * 8191)\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n\n    client = await aiohttp_client(app)\n\n    async with await client.get(\"/\", max_line_size=8191) as resp:\n        assert resp.reason == \"x\" * 8191\n\n\n@pytest.mark.xfail(raises=asyncio.TimeoutError, reason=\"#7599\")\nasync def test_rejected_upload(\n    aiohttp_client: AiohttpClient, tmp_path: pathlib.Path\n) -> None:\n    async def ok_handler(request: web.Request) -> web.Response:\n        return web.Response()\n\n    async def not_ok_handler(request: web.Request) -> NoReturn:\n        raise web.HTTPBadRequest()\n\n    app = web.Application()\n    app.router.add_get(\"/ok\", ok_handler)\n    app.router.add_post(\"/not_ok\", not_ok_handler)\n    client = await aiohttp_client(app)\n\n    file_size_bytes = 1024 * 1024\n    file_path = tmp_path / \"uploaded.txt\"\n    file_path.write_text(\"0\" * file_size_bytes, encoding=\"utf8\")\n\n    with open(file_path, \"rb\") as file:\n        data = {\"file\": file}\n        async with await client.post(\"/not_ok\", data=data) as resp_not_ok:\n            assert 400 == resp_not_ok.status\n\n    async with await client.get(\n        \"/ok\", timeout=aiohttp.ClientTimeout(total=0.01)\n    ) as resp_ok:\n        assert 200 == resp_ok.status\n\n\nasync def test_request_with_wrong_ssl_type(aiohttp_client: AiohttpClient) -> None:\n    app = web.Application()\n    session = await aiohttp_client(app)\n\n    with pytest.raises(TypeError, match=\"ssl should be SSLContext, Fingerprint, .*\"):\n        await session.get(\"/\", ssl=42)  # type: ignore[arg-type]\n\n\n@pytest.mark.parametrize(\n    (\"value\", \"exc_type\"),\n    [(42, TypeError), (\"InvalidUrl\", InvalidURL)],\n)\nasync def test_request_with_wrong_proxy(\n    aiohttp_client: AiohttpClient, value: Union[int, str], exc_type: Type[Exception]\n) -> None:\n    app = web.Application()\n    session = await aiohttp_client(app)\n\n    with pytest.raises(exc_type):\n        await session.get(\"/\", proxy=value)  # type: ignore[arg-type]\n\n\nasync def test_raise_for_status_is_none(aiohttp_client: AiohttpClient) -> None:\n    async def handler(_: web.Request) -> web.Response:\n        return web.Response()\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n    session = await aiohttp_client(app, raise_for_status=None)\n\n    await session.get(\"/\")\n\n\n@pytest.mark.xfail(\n    reason=\"#8395 Error message regression for large headers in 3.9.4\",\n    raises=AssertionError,\n)\nasync def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n    \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n\n    async def handler(_: web.Request) -> web.Response:\n        return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n\n    app = web.Application()\n    app.add_routes([web.get(\"/\", handler)])\n    client = await aiohttp_client(app)\n\n    with pytest.raises(\n        aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n    ) as exc_info:\n        await client.get(\"/\")\n    assert exc_info.value.status == 400\n\n\nasync def test_exception_when_read_outside_of_session(\n    aiohttp_server: AiohttpServer,\n) -> None:\n    async def handler(request: web.Request) -> web.Response:\n        return web.Response(body=b\"1\" * 1000000)\n\n    app = web.Application()\n    app.router.add_get(\"/\", handler)\n\n    server = await aiohttp_server(app)\n    async with aiohttp.ClientSession() as sess:\n        resp = await sess.get(server.make_url(\"/\"))\n\n    with pytest.raises(RuntimeError, match=\"Connection closed\"):\n        await resp.read()\n",
        "# type: ignore\nimport asyncio\nimport base64\nimport os\nimport socket\nimport ssl\nimport sys\nfrom hashlib import md5, sha1, sha256\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\nfrom typing import Any, List\nfrom unittest import mock\nfrom uuid import uuid4\n\nimport pytest\n\nfrom aiohttp.http import WS_KEY\nfrom aiohttp.test_utils import loop_context\n\ntry:\n    import trustme\n\n    # Check if the CA is available in runtime, MacOS on Py3.10 fails somehow\n    trustme.CA()\n\n    TRUSTME: bool = True\nexcept ImportError:\n    TRUSTME = False\n\npytest_plugins: List[str] = [\"aiohttp.pytest_plugin\", \"pytester\"]\n\nIS_HPUX = sys.platform.startswith(\"hp-ux\")\nIS_LINUX = sys.platform.startswith(\"linux\")\n\n\n@pytest.fixture\ndef tls_certificate_authority() -> trustme.CA:\n    if not TRUSTME:\n        pytest.xfail(\"trustme is not supported\")\n    return trustme.CA()\n\n\n@pytest.fixture\ndef tls_certificate(tls_certificate_authority: Any) -> Any:\n    return tls_certificate_authority.issue_cert(\n        \"localhost\",\n        \"xn--prklad-4va.localhost\",\n        \"127.0.0.1\",\n        \"::1\",\n    )\n\n\n@pytest.fixture\ndef ssl_ctx(tls_certificate: Any) -> ssl.SSLContext:\n    ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n    tls_certificate.configure_cert(ssl_ctx)\n    return ssl_ctx\n\n\n@pytest.fixture\ndef client_ssl_ctx(tls_certificate_authority: Any) -> ssl.SSLContext:\n    ssl_ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)\n    tls_certificate_authority.configure_trust(ssl_ctx)\n    return ssl_ctx\n\n\n@pytest.fixture\ndef tls_ca_certificate_pem_path(tls_certificate_authority: Any) -> None:\n    with tls_certificate_authority.cert_pem.tempfile() as ca_cert_pem:\n        yield ca_cert_pem\n\n\n@pytest.fixture\ndef tls_certificate_pem_path(tls_certificate: Any) -> None:\n    with tls_certificate.private_key_and_cert_chain_pem.tempfile() as cert_pem:\n        yield cert_pem\n\n\n@pytest.fixture\ndef tls_certificate_pem_bytes(tls_certificate: Any) -> bytes:\n    return tls_certificate.cert_chain_pems[0].bytes()\n\n\n@pytest.fixture\ndef tls_certificate_fingerprint_sha256(tls_certificate_pem_bytes: Any) -> bytes:\n    tls_cert_der = ssl.PEM_cert_to_DER_cert(tls_certificate_pem_bytes.decode())\n    return sha256(tls_cert_der).digest()\n\n\n@pytest.fixture\ndef pipe_name() -> str:\n    name = rf\"\\\\.\\pipe\\{uuid4().hex}\"\n    return name\n\n\n@pytest.fixture\ndef create_mocked_conn(loop: Any):\n    def _proto_factory(conn_closing_result=None, **kwargs):\n        proto = mock.Mock(**kwargs)\n        proto.closed = loop.create_future()\n        proto.closed.set_result(conn_closing_result)\n        return proto\n\n    yield _proto_factory\n\n\n@pytest.fixture\ndef unix_sockname(tmp_path: Any, tmp_path_factory: Any):\n    # Generate an fs path to the UNIX domain socket for testing.\n\n    # N.B. Different OS kernels have different fs path length limitations\n    # for it. For Linux, it's 108, for HP-UX it's 92 (or higher) depending\n    # on its version. For most of the BSDs (Open, Free, macOS) it's\n    # mostly 104 but sometimes it can be down to 100.\n\n    # Ref: https://github.com/aio-libs/aiohttp/issues/3572\n    if not hasattr(socket, \"AF_UNIX\"):\n        pytest.skip(\"requires UNIX sockets\")\n\n    max_sock_len = 92 if IS_HPUX else 108 if IS_LINUX else 100\n    # Amount of bytes allocated for the UNIX socket path by OS kernel.\n    # Ref: https://unix.stackexchange.com/a/367012/27133\n\n    sock_file_name = \"unix.sock\"\n    unique_prefix = f\"{uuid4()!s}-\"\n    unique_prefix_len = len(unique_prefix.encode())\n\n    root_tmp_dir = Path(\"/tmp\").resolve()\n    os_tmp_dir = Path(os.getenv(\"TMPDIR\", \"/tmp\")).resolve()\n    original_base_tmp_path = Path(\n        str(tmp_path_factory.getbasetemp()),\n    ).resolve()\n\n    original_base_tmp_path_hash = md5(\n        str(original_base_tmp_path).encode(),\n    ).hexdigest()\n\n    def make_tmp_dir(base_tmp_dir):\n        return TemporaryDirectory(\n            dir=str(base_tmp_dir),\n            prefix=\"pt-\",\n            suffix=f\"-{original_base_tmp_path_hash!s}\",\n        )\n\n    def assert_sock_fits(sock_path):\n        sock_path_len = len(sock_path.encode())\n        # exit-check to verify that it's correct and simplify debugging\n        # in the future\n        assert sock_path_len <= max_sock_len, (\n            \"Suggested UNIX socket ({sock_path}) is {sock_path_len} bytes \"\n            \"long but the current kernel only has {max_sock_len} bytes \"\n            \"allocated to hold it so it must be shorter. \"\n            \"See https://github.com/aio-libs/aiohttp/issues/3572 \"\n            \"for more info.\"\n        ).format_map(locals())\n\n    paths = original_base_tmp_path, os_tmp_dir, root_tmp_dir\n    unique_paths = [p for n, p in enumerate(paths) if p not in paths[:n]]\n    paths_num = len(unique_paths)\n\n    for num, tmp_dir_path in enumerate(paths, 1):\n        with make_tmp_dir(tmp_dir_path) as tmpd:\n            tmpd = Path(tmpd).resolve()\n            sock_path = str(tmpd / sock_file_name)\n            sock_path_len = len(sock_path.encode())\n\n            if num >= paths_num:\n                # exit-check to verify that it's correct and simplify\n                # debugging in the future\n                assert_sock_fits(sock_path)\n\n            if sock_path_len <= max_sock_len:\n                if max_sock_len - sock_path_len >= unique_prefix_len:\n                    # If we're lucky to have extra space in the path,\n                    # let's also make it more unique\n                    sock_path = str(tmpd / \"\".join((unique_prefix, sock_file_name)))\n                    # Double-checking it:\n                    assert_sock_fits(sock_path)\n                yield sock_path\n                return\n\n\n@pytest.fixture\ndef selector_loop() -> None:\n    policy = asyncio.WindowsSelectorEventLoopPolicy()\n    asyncio.set_event_loop_policy(policy)\n\n    with loop_context(policy.new_event_loop) as _loop:\n        asyncio.set_event_loop(_loop)\n        yield _loop\n\n\n@pytest.fixture\ndef netrc_contents(\n    tmp_path: Path,\n    monkeypatch: pytest.MonkeyPatch,\n    request: pytest.FixtureRequest,\n):\n    \"\"\"\n    Prepare :file:`.netrc` with given contents.\n\n    Monkey-patches :envvar:`NETRC` to point to created file.\n    \"\"\"\n    netrc_contents = getattr(request, \"param\", None)\n\n    netrc_file_path = tmp_path / \".netrc\"\n    if netrc_contents is not None:\n        netrc_file_path.write_text(netrc_contents)\n\n    monkeypatch.setenv(\"NETRC\", str(netrc_file_path))\n\n    return netrc_file_path\n\n\n@pytest.fixture\ndef start_connection():\n    with mock.patch(\n        \"aiohttp.connector.aiohappyeyeballs.start_connection\",\n        autospec=True,\n        spec_set=True,\n    ) as start_connection_mock:\n        yield start_connection_mock\n\n\n@pytest.fixture\ndef key_data() -> bytes:\n    return os.urandom(16)\n\n\n@pytest.fixture\ndef key(key_data: bytes) -> bytes:\n    return base64.b64encode(key_data)\n\n\n@pytest.fixture\ndef ws_key(key: bytes) -> bytes:\n    return base64.b64encode(sha1(key + WS_KEY).digest()).decode()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "conftest.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "re-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/requirements/cython.txt\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/tools/gen.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/hdrs.py\n./tools/gen.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_helpers.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_writer.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_websocket.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_helpers.pyi\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_cparser.pxd\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_find_header.pxd\ncython -3 -o aiohttp/_helpers.c aiohttp/_helpers.pyx -I aiohttp -Werror\ncython -3 -o aiohttp/_http_parser.c aiohttp/_http_parser.pyx -I aiohttp -Werror\ncython -3 -o aiohttp/_http_writer.c aiohttp/_http_writer.pyx -I aiohttp -Werror\ncython -3 -o aiohttp/_websocket.c aiohttp/_websocket.pyx -I aiohttp -Werror\ncd vendor/llhttp; npm ci\n\n> llhttp@9.2.1 prepare\n> npm run clean && npm run build-ts\n\n\n> llhttp@9.2.1 clean\n> rm -rf lib && rm -rf test/tmp\n\n\n> llhttp@9.2.1 build-ts\n> tsc\n\n\nadded 213 packages, and audited 214 packages in 5s\n\n41 packages are looking for funding\n  run `npm fund` for details\n\n5 vulnerabilities (3 moderate, 2 high)\n\nTo address issues that do not require attention, run:\n  npm audit fix\n\nSome issues need review, and may require choosing\na different dependency.\n\nRun `npm audit` for details.\nmake -C vendor/llhttp generate\nmake[1]: Entering directory '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/vendor/llhttp'\nnpx ts-node bin/generate.ts\nmake[1]: Leaving directory '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/vendor/llhttp'\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/__init__.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/abc.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/base_protocol.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/client.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/client_exceptions.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/client_proto.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/client_reqrep.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/client_ws.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/compression_utils.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/connector.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/cookiejar.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/formdata.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/helpers.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/http.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/http_exceptions.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/http_parser.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/http_websocket.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/http_writer.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/locks.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/log.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/multipart.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/payload.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/pytest_plugin.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/resolver.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/streams.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/tcp_helpers.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/test_utils.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/tracing.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/typedefs.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_app.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_exceptions.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_fileresponse.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_log.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_middlewares.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_protocol.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_request.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_response.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_routedef.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_runner.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_server.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_urldispatcher.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_ws.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/worker.py\nuv pip install -e . -c requirements/runtime-deps.txt\n",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 1ms\nPrepared 1 package in 0.31ms\nInstalled 1 package in 37ms\n + pip==24.3.1\nResolved 2 packages in 9ms\nInstalled 2 packages in 12ms\n + cython==3.0.11\n + multidict==6.0.5\nResolved 99 packages in 67ms\nUninstalled 1 package in 5ms\nInstalled 98 packages in 243ms\n + aiodns==3.2.0\n + aiohappyeyeballs==2.4.0\n + aiohttp-theme==0.1.6\n + aioredis==2.0.1\n + aiosignal==1.3.1\n + alabaster==0.7.13\n + annotated-types==0.7.0\n + async-timeout==4.0.3\n + babel==2.16.0\n + blockdiag==3.0.0\n + brotli==1.1.0\n + build==1.2.1\n + certifi==2024.8.30\n + cffi==1.17.0\n + cfgv==3.4.0\n + charset-normalizer==3.3.2\n + cherry-picker==2.2.0\n + click==8.1.7\n + coverage==7.6.1\n + cryptography==43.0.0\n + distlib==0.3.8\n + docutils==0.20.1\n + exceptiongroup==1.2.2\n + filelock==3.15.4\n + freezegun==1.5.1\n + frozenlist==1.4.1\n + funcparserlib==1.0.1\n + gidgethub==5.3.0\n + gunicorn==23.0.0\n + identify==2.6.0\n + idna==3.4\n + imagesize==1.4.1\n + importlib-metadata==8.4.0\n + importlib-resources==6.4.4\n + incremental==24.7.2\n + iniconfig==2.0.0\n + jinja2==3.1.4\n + markdown-it-py==3.0.0\n + markupsafe==2.1.5\n + mdurl==0.1.2\n + mypy==1.11.2\n + mypy-extensions==1.0.0\n + nodeenv==1.9.1\n + packaging==24.1\n + pillow==9.5.0\n - pip==24.3.1\n + pip==24.2\n + pip-tools==7.4.1\n + platformdirs==4.2.2\n + pluggy==1.5.0\n + pre-commit==3.5.0\n + proxy-py==2.4.7\n + pycares==4.4.0\n + pycparser==2.22\n + pydantic==2.8.2\n + pydantic-core==2.20.1\n + pygments==2.18.0\n + pyjwt==2.8.0\n + pyproject-hooks==1.1.0\n + pytest==8.1.1\n + pytest-cov==5.0.0\n + pytest-mock==3.14.0\n + python-dateutil==2.9.0.post0\n + python-on-whales==0.72.0\n + pyyaml==6.0.2\n + re-assert==1.1.0\n + regex==2024.7.24\n + requests==2.32.3\n + rich==13.8.0\n + setuptools==74.0.0\n + setuptools-git==1.2\n + shellingham==1.5.4\n + six==1.16.0\n + slotscheck==0.19.0\n + snowballstemmer==2.2.0\n + sphinx==7.1.2\n + sphinxcontrib-applehelp==1.0.4\n + sphinxcontrib-blockdiag==3.0.0\n + sphinxcontrib-devhelp==1.0.2\n + sphinxcontrib-htmlhelp==2.0.1\n + sphinxcontrib-jsmath==1.0.1\n + sphinxcontrib-qthelp==1.0.3\n + sphinxcontrib-serializinghtml==1.1.5\n + sphinxcontrib-towncrier==0.4.0a0\n + tomli==2.0.1\n + towncrier==23.11.0\n + tqdm==4.66.5\n + trustme==1.1.0\n + typer==0.12.5\n + typing-extensions==4.12.2\n + uritemplate==4.1.1\n + urllib3==2.2.2\n + uvloop==0.20.0\n + virtualenv==20.26.3\n + wait-for-it==2.2.2\n + webcolors==24.8.0\n + wheel==0.44.0\n + yarl==1.9.6\n + zipp==3.20.1\nwarning: `yarl==1.9.6` is yanked (reason: \"Performance regression: https://github.com/aio-libs/yarl/pull/1198\")\nResolved 8 packages in 1.70s\nPrepared 1 package in 17.02s\nInstalled 1 package in 0.54ms\n + aiohttp==4.0.0a2.dev0 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4)\nResolved 24 packages in 16ms\nInstalled 5 packages in 5ms\n + async-generator==1.10\n + brotlipy==0.7.0\n + chardet==5.2.0\n + multdict==0.0.5\n + pytest-asyncio==0.23.8\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.9.21, pytest-8.1.1, pluggy-1.5.0 -- /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/.venv/bin/python\ncachedir: .pytest_cache\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4\nconfigfile: setup.cfg\nplugins: cov-5.0.0, mock-3.14.0, asyncio-0.23.8\nasyncio: mode=strict\ncollecting ... collected 226 items\n\nr2e_tests/test_1.py::test_keepalive_two_requests_success[pyloop] PASSED  [  0%]\nr2e_tests/test_1.py::test_keepalive_after_head_requests_success[pyloop] PASSED [  0%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-101] PASSED [  1%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-204] PASSED [  1%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-304] PASSED [  2%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-101] PASSED [  2%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-204] PASSED [  3%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-304] PASSED [  3%]\nr2e_tests/test_1.py::test_keepalive_response_released[pyloop] PASSED     [  3%]\nr2e_tests/test_1.py::test_upgrade_connection_not_released_after_read[pyloop] PASSED [  4%]\nr2e_tests/test_1.py::test_keepalive_server_force_close_connection[pyloop] PASSED [  4%]\nr2e_tests/test_1.py::test_keepalive_timeout_async_sleep PASSED           [  5%]\nr2e_tests/test_1.py::test_keepalive_timeout_sync_sleep PASSED            [  5%]\nr2e_tests/test_1.py::test_release_early[pyloop] PASSED                   [  6%]\nr2e_tests/test_1.py::test_HTTP_304[pyloop] PASSED                        [  6%]\nr2e_tests/test_1.py::test_stream_request_on_server_eof[pyloop] PASSED    [  7%]\nr2e_tests/test_1.py::test_stream_request_on_server_eof_nested[pyloop] PASSED [  7%]\nr2e_tests/test_1.py::test_HTTP_304_WITH_BODY[pyloop] PASSED              [  7%]\nr2e_tests/test_1.py::test_auto_header_user_agent[pyloop] PASSED          [  8%]\nr2e_tests/test_1.py::test_skip_auto_headers_user_agent[pyloop] PASSED    [  8%]\nr2e_tests/test_1.py::test_skip_default_auto_headers_user_agent[pyloop] PASSED [  9%]\nr2e_tests/test_1.py::test_skip_auto_headers_content_type[pyloop] PASSED  [  9%]\nr2e_tests/test_1.py::test_post_data_bytesio[pyloop] PASSED               [ 10%]\nr2e_tests/test_1.py::test_post_data_with_bytesio_file[pyloop] PASSED     [ 10%]\nr2e_tests/test_1.py::test_post_data_stringio[pyloop] PASSED              [ 11%]\nr2e_tests/test_1.py::test_post_data_textio_encoding[pyloop] PASSED       [ 11%]\nr2e_tests/test_1.py::test_post_data_zipfile_filelike[pyloop] PASSED      [ 11%]\nr2e_tests/test_1.py::test_post_data_tarfile_filelike[pyloop] PASSED      [ 12%]\nr2e_tests/test_1.py::test_ssl_client[pyloop] PASSED                      [ 12%]\nr2e_tests/test_1.py::test_tcp_connector_fingerprint_ok[pyloop] PASSED    [ 13%]\nr2e_tests/test_1.py::test_tcp_connector_fingerprint_fail[pyloop] PASSED  [ 13%]\nr2e_tests/test_1.py::test_format_task_get[pyloop] PASSED                 [ 14%]\nr2e_tests/test_1.py::test_str_params[pyloop] PASSED                      [ 14%]\nr2e_tests/test_1.py::test_drop_params_on_redirect[pyloop] PASSED         [ 15%]\nr2e_tests/test_1.py::test_drop_fragment_on_redirect[pyloop] PASSED       [ 15%]\nr2e_tests/test_1.py::test_drop_fragment[pyloop] PASSED                   [ 15%]\nr2e_tests/test_1.py::test_history[pyloop] PASSED                         [ 16%]\nr2e_tests/test_1.py::test_keepalive_closed_by_server[pyloop] PASSED      [ 16%]\nr2e_tests/test_1.py::test_wait_for[pyloop] PASSED                        [ 17%]\nr2e_tests/test_1.py::test_raw_headers[pyloop] PASSED                     [ 17%]\nr2e_tests/test_1.py::test_host_header_first[pyloop] PASSED               [ 18%]\nr2e_tests/test_1.py::test_empty_header_values[pyloop] PASSED             [ 18%]\nr2e_tests/test_1.py::test_204_with_gzipped_content_encoding[pyloop] PASSED [ 19%]\nr2e_tests/test_1.py::test_timeout_on_reading_headers[pyloop] PASSED      [ 19%]\nr2e_tests/test_1.py::test_timeout_on_conn_reading_headers[pyloop] PASSED [ 19%]\nr2e_tests/test_1.py::test_timeout_on_session_read_timeout[pyloop] PASSED [ 20%]\nr2e_tests/test_1.py::test_read_timeout_between_chunks[pyloop] PASSED     [ 20%]\nr2e_tests/test_1.py::test_read_timeout_on_reading_chunks[pyloop] PASSED  [ 21%]\nr2e_tests/test_1.py::test_read_timeout_on_write[pyloop] PASSED           [ 21%]\nr2e_tests/test_1.py::test_timeout_on_reading_data[pyloop] PASSED         [ 22%]\nr2e_tests/test_1.py::test_timeout_none[pyloop] PASSED                    [ 22%]\nr2e_tests/test_1.py::test_readline_error_on_conn_close[pyloop] PASSED    [ 23%]\nr2e_tests/test_1.py::test_no_error_on_conn_close_if_eof[pyloop] PASSED   [ 23%]\nr2e_tests/test_1.py::test_error_not_overwrote_on_conn_close[pyloop] PASSED [ 23%]\nr2e_tests/test_1.py::test_HTTP_200_OK_METHOD[pyloop] PASSED              [ 24%]\nr2e_tests/test_1.py::test_HTTP_200_OK_METHOD_connector[pyloop] PASSED    [ 24%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_GET[pyloop] PASSED           [ 25%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_HEAD[pyloop] PASSED          [ 25%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_NON_HTTP[pyloop] PASSED      [ 26%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST[pyloop] PASSED          [ 26%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST_with_content_length_hdr[pyloop] PASSED [ 26%]\nr2e_tests/test_1.py::test_HTTP_307_REDIRECT_POST[pyloop] PASSED          [ 27%]\nr2e_tests/test_1.py::test_HTTP_308_PERMANENT_REDIRECT_POST[pyloop] PASSED [ 27%]\nr2e_tests/test_1.py::test_HTTP_302_max_redirects[pyloop] PASSED          [ 28%]\nr2e_tests/test_1.py::test_HTTP_200_GET_WITH_PARAMS[pyloop] PASSED        [ 28%]\nr2e_tests/test_1.py::test_HTTP_200_GET_WITH_MultiDict_PARAMS[pyloop] PASSED [ 29%]\nr2e_tests/test_1.py::test_HTTP_200_GET_WITH_MIXED_PARAMS[pyloop] PASSED  [ 29%]\nr2e_tests/test_1.py::test_POST_DATA[pyloop] PASSED                       [ 30%]\nr2e_tests/test_1.py::test_POST_DATA_with_explicit_formdata[pyloop] PASSED [ 30%]\nr2e_tests/test_1.py::test_POST_DATA_with_charset[pyloop] PASSED          [ 30%]\nr2e_tests/test_1.py::test_POST_DATA_formdats_with_charset[pyloop] PASSED [ 31%]\nr2e_tests/test_1.py::test_POST_DATA_with_charset_post[pyloop] PASSED     [ 31%]\nr2e_tests/test_1.py::test_POST_MultiDict[pyloop] PASSED                  [ 32%]\nr2e_tests/test_1.py::test_POST_DATA_DEFLATE[pyloop] PASSED               [ 32%]\nr2e_tests/test_1.py::test_POST_FILES[pyloop] PASSED                      [ 33%]\nr2e_tests/test_1.py::test_POST_FILES_DEFLATE[pyloop] PASSED              [ 33%]\nr2e_tests/test_1.py::test_POST_bytes[pyloop] PASSED                      [ 34%]\nr2e_tests/test_1.py::test_POST_bytes_too_large[pyloop] PASSED            [ 34%]\nr2e_tests/test_1.py::test_POST_FILES_STR[pyloop] PASSED                  [ 34%]\nr2e_tests/test_1.py::test_POST_FILES_STR_SIMPLE[pyloop] PASSED           [ 35%]\nr2e_tests/test_1.py::test_POST_FILES_LIST[pyloop] PASSED                 [ 35%]\nr2e_tests/test_1.py::test_POST_FILES_CT[pyloop] PASSED                   [ 36%]\nr2e_tests/test_1.py::test_POST_FILES_SINGLE[pyloop] PASSED               [ 36%]\nr2e_tests/test_1.py::test_POST_FILES_SINGLE_content_disposition[pyloop] PASSED [ 37%]\nr2e_tests/test_1.py::test_POST_FILES_SINGLE_BINARY[pyloop] PASSED        [ 37%]\nr2e_tests/test_1.py::test_POST_FILES_IO[pyloop] PASSED                   [ 38%]\nr2e_tests/test_1.py::test_POST_FILES_IO_WITH_PARAMS[pyloop] PASSED       [ 38%]\nr2e_tests/test_1.py::test_POST_FILES_WITH_DATA[pyloop] PASSED            [ 38%]\nr2e_tests/test_1.py::test_POST_STREAM_DATA[pyloop] PASSED                [ 39%]\nr2e_tests/test_1.py::test_json[pyloop] PASSED                            [ 39%]\nr2e_tests/test_1.py::test_json_custom[pyloop] PASSED                     [ 40%]\nr2e_tests/test_1.py::test_expect_continue[pyloop] PASSED                 [ 40%]\nr2e_tests/test_1.py::test_encoding_deflate[pyloop] PASSED                [ 41%]\nr2e_tests/test_1.py::test_encoding_deflate_nochunk[pyloop] PASSED        [ 41%]\nr2e_tests/test_1.py::test_encoding_gzip[pyloop] PASSED                   [ 42%]\nr2e_tests/test_1.py::test_encoding_gzip_write_by_chunks[pyloop] PASSED   [ 42%]\nr2e_tests/test_1.py::test_encoding_gzip_nochunk[pyloop] PASSED           [ 42%]\nr2e_tests/test_1.py::test_bad_payload_compression[pyloop] PASSED         [ 43%]\nr2e_tests/test_1.py::test_bad_payload_chunked_encoding[pyloop] PASSED    [ 43%]\nr2e_tests/test_1.py::test_no_payload_304_with_chunked_encoding[pyloop] PASSED [ 44%]\nr2e_tests/test_1.py::test_head_request_with_chunked_encoding[pyloop] PASSED [ 44%]\nr2e_tests/test_1.py::test_no_payload_200_with_chunked_encoding[pyloop] PASSED [ 45%]\nr2e_tests/test_1.py::test_bad_payload_content_length[pyloop] PASSED      [ 45%]\nr2e_tests/test_1.py::test_payload_content_length_by_chunks[pyloop] PASSED [ 46%]\nr2e_tests/test_1.py::test_chunked[pyloop] PASSED                         [ 46%]\nr2e_tests/test_1.py::test_shortcuts[pyloop] PASSED                       [ 46%]\nr2e_tests/test_1.py::test_cookies[pyloop] PASSED                         [ 47%]\nr2e_tests/test_1.py::test_cookies_per_request[pyloop] PASSED             [ 47%]\nr2e_tests/test_1.py::test_cookies_redirect[pyloop] PASSED                [ 48%]\nr2e_tests/test_1.py::test_cookies_on_empty_session_jar[pyloop] PASSED    [ 48%]\nr2e_tests/test_1.py::test_morsel_with_attributes[pyloop] PASSED          [ 49%]\nr2e_tests/test_1.py::test_set_cookies[pyloop] PASSED                     [ 49%]\nr2e_tests/test_1.py::test_set_cookies_expired[pyloop] PASSED             [ 50%]\nr2e_tests/test_1.py::test_set_cookies_max_age[pyloop] PASSED             [ 50%]\nr2e_tests/test_1.py::test_set_cookies_max_age_overflow[pyloop] PASSED    [ 50%]\nr2e_tests/test_1.py::test_request_conn_error PASSED                      [ 51%]\nr2e_tests/test_1.py::test_broken_connection[pyloop] XFAIL                [ 51%]\nr2e_tests/test_1.py::test_broken_connection_2[pyloop] PASSED             [ 52%]\nr2e_tests/test_1.py::test_custom_headers[pyloop] PASSED                  [ 52%]\nr2e_tests/test_1.py::test_redirect_to_absolute_url[pyloop] PASSED        [ 53%]\nr2e_tests/test_1.py::test_redirect_without_location_header[pyloop] PASSED [ 53%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http://:/-http://:/-InvalidUrlClientError] PASSED [ 53%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlClientError] PASSED [ 54%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http:/-http:///-InvalidUrlClientError] PASSED [ 54%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http:/example.com-http:///example.com-InvalidUrlClientError] PASSED [ 55%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http:///example.com-http:///example.com-InvalidUrlClientError] PASSED [ 55%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[call:+380123456789-call:\\\\+380123456789-NonHttpUrlClientError] PASSED [ 56%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[skype:handle-skype:handle-NonHttpUrlClientError] PASSED [ 56%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[slack://instance/room-slack://instance/room-NonHttpUrlClientError] PASSED [ 57%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[steam:code-steam:code-NonHttpUrlClientError] PASSED [ 57%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[twitter://handle-twitter://handle-NonHttpUrlClientError] PASSED [ 57%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlClientError] PASSED [ 58%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/-http:///-InvalidUrlRedirectClientError] PASSED [ 58%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 59%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 59%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError] PASSED [ 60%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError] PASSED [ 60%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError] PASSED [ 61%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError] PASSED [ 61%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError] PASSED [ 61%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError] PASSED [ 62%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError] PASSED [ 62%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError] PASSED [ 63%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/-http:///-InvalidUrlRedirectClientError] PASSED [ 63%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 64%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 64%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError] PASSED [ 65%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError] PASSED [ 65%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError] PASSED [ 65%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError] PASSED [ 66%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError] PASSED [ 66%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError] PASSED [ 67%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError] PASSED [ 67%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError] PASSED [ 68%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-200-True] PASSED         [ 68%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-201-True] PASSED         [ 69%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-301-True] PASSED         [ 69%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-400-False] PASSED        [ 69%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-403-False] PASSED        [ 70%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-500-False] PASSED        [ 70%]\nr2e_tests/test_1.py::test_raise_for_status[pyloop] PASSED                [ 71%]\nr2e_tests/test_1.py::test_raise_for_status_per_request[pyloop] PASSED    [ 71%]\nr2e_tests/test_1.py::test_raise_for_status_disable_per_request[pyloop] PASSED [ 72%]\nr2e_tests/test_1.py::test_request_raise_for_status_default[pyloop] PASSED [ 72%]\nr2e_tests/test_1.py::test_request_raise_for_status_disabled[pyloop] PASSED [ 73%]\nr2e_tests/test_1.py::test_request_raise_for_status_enabled[pyloop] PASSED [ 73%]\nr2e_tests/test_1.py::test_session_raise_for_status_coro[pyloop] PASSED   [ 73%]\nr2e_tests/test_1.py::test_request_raise_for_status_coro[pyloop] PASSED   [ 74%]\nr2e_tests/test_1.py::test_invalid_idna PASSED                            [ 74%]\nr2e_tests/test_1.py::test_creds_in_auth_and_url PASSED                   [ 75%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts] PASSED [ 75%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-http -> https] PASSED [ 76%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-https -> http] PASSED [ 76%]\nr2e_tests/test_1.py::test_auth_persist_on_redirect_to_other_host_with_global_auth[pyloop] PASSED [ 76%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url[pyloop] PASSED [ 77%]\nr2e_tests/test_1.py::test_async_with_session PASSED                      [ 77%]\nr2e_tests/test_1.py::test_session_close_awaitable PASSED                 [ 78%]\nr2e_tests/test_1.py::test_close_resp_on_error_async_with_session[pyloop] PASSED [ 78%]\nr2e_tests/test_1.py::test_release_resp_on_normal_exit_from_cm[pyloop] PASSED [ 79%]\nr2e_tests/test_1.py::test_non_close_detached_session_on_error_cm[pyloop] PASSED [ 79%]\nr2e_tests/test_1.py::test_close_detached_session_on_non_existing_addr PASSED [ 80%]\nr2e_tests/test_1.py::test_aiohttp_request_context_manager[pyloop] PASSED [ 80%]\nr2e_tests/test_1.py::test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop] PASSED [ 80%]\nr2e_tests/test_1.py::test_aiohttp_request_ctx_manager_not_found PASSED   [ 81%]\nr2e_tests/test_1.py::test_aiohttp_request_coroutine[pyloop] PASSED       [ 81%]\nr2e_tests/test_1.py::test_yield_from_in_session_request[pyloop] PASSED   [ 82%]\nr2e_tests/test_1.py::test_close_context_manager[pyloop] PASSED           [ 82%]\nr2e_tests/test_1.py::test_session_auth[pyloop] PASSED                    [ 83%]\nr2e_tests/test_1.py::test_session_auth_override[pyloop] PASSED           [ 83%]\nr2e_tests/test_1.py::test_session_auth_header_conflict[pyloop] PASSED    [ 84%]\nr2e_tests/test_1.py::test_session_headers[pyloop] PASSED                 [ 84%]\nr2e_tests/test_1.py::test_session_headers_merge[pyloop] PASSED           [ 84%]\nr2e_tests/test_1.py::test_multidict_headers[pyloop] PASSED               [ 85%]\nr2e_tests/test_1.py::test_request_conn_closed[pyloop] PASSED             [ 85%]\nr2e_tests/test_1.py::test_dont_close_explicit_connector[pyloop] PASSED   [ 86%]\nr2e_tests/test_1.py::test_server_close_keepalive_connection PASSED       [ 86%]\nr2e_tests/test_1.py::test_handle_keepalive_on_closed_connection PASSED   [ 87%]\nr2e_tests/test_1.py::test_error_in_performing_request[pyloop] PASSED     [ 87%]\nr2e_tests/test_1.py::test_await_after_cancelling[pyloop] PASSED          [ 88%]\nr2e_tests/test_1.py::test_async_payload_generator[pyloop] PASSED         [ 88%]\nr2e_tests/test_1.py::test_read_from_closed_response[pyloop] PASSED       [ 88%]\nr2e_tests/test_1.py::test_read_from_closed_response2[pyloop] PASSED      [ 89%]\nr2e_tests/test_1.py::test_read_from_closed_content[pyloop] PASSED        [ 89%]\nr2e_tests/test_1.py::test_read_timeout[pyloop] PASSED                    [ 90%]\nr2e_tests/test_1.py::test_socket_timeout[pyloop] PASSED                  [ 90%]\nr2e_tests/test_1.py::test_read_timeout_closes_connection[pyloop] PASSED  [ 91%]\nr2e_tests/test_1.py::test_read_timeout_on_prepared_response[pyloop] PASSED [ 91%]\nr2e_tests/test_1.py::test_timeout_with_full_buffer[pyloop] PASSED        [ 92%]\nr2e_tests/test_1.py::test_read_bufsize_session_default[pyloop] PASSED    [ 92%]\nr2e_tests/test_1.py::test_read_bufsize_explicit[pyloop] PASSED           [ 92%]\nr2e_tests/test_1.py::test_http_empty_data_text[pyloop] PASSED            [ 93%]\nr2e_tests/test_1.py::test_max_field_size_session_default[pyloop] PASSED  [ 93%]\nr2e_tests/test_1.py::test_max_field_size_session_default_fail[pyloop] PASSED [ 94%]\nr2e_tests/test_1.py::test_max_field_size_session_explicit[pyloop] PASSED [ 94%]\nr2e_tests/test_1.py::test_max_field_size_request_explicit[pyloop] PASSED [ 95%]\nr2e_tests/test_1.py::test_max_line_size_session_default[pyloop] PASSED   [ 95%]\nr2e_tests/test_1.py::test_max_line_size_session_default_fail[pyloop] PASSED [ 96%]\nr2e_tests/test_1.py::test_max_line_size_session_explicit[pyloop] PASSED  [ 96%]\nr2e_tests/test_1.py::test_max_line_size_request_explicit[pyloop] PASSED  [ 96%]\nr2e_tests/test_1.py::test_rejected_upload[pyloop] XFAIL (#7599)          [ 97%]\nr2e_tests/test_1.py::test_request_with_wrong_ssl_type[pyloop] PASSED     [ 97%]\nr2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-42-TypeError] PASSED [ 98%]\nr2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-InvalidUrl-InvalidURL] PASSED [ 98%]\nr2e_tests/test_1.py::test_raise_for_status_is_none[pyloop] PASSED        [ 99%]\nr2e_tests/test_1.py::test_header_too_large_error[pyloop] XFAIL (#839...) [ 99%]\nr2e_tests/test_1.py::test_exception_when_read_outside_of_session[pyloop] PASSED [100%]\n\n================================== XFAILURES ===================================\n________________________ test_broken_connection[pyloop] ________________________\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9306790>\n\n    @pytest.mark.xfail\n    async def test_broken_connection(aiohttp_client: AiohttpClient) -> None:\n        async def handler(request: web.Request) -> web.Response:\n            assert request.transport is not None\n            request.transport.close()\n            return web.Response(text=\"answer\" * 1000)\n    \n        app = web.Application()\n        app.router.add_get(\"/\", handler)\n        client = await aiohttp_client(app)\n    \n        with pytest.raises(aiohttp.ClientResponseError):\n>           await client.get(\"/\")\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9306790>\napp        = <Application 0x7691ca062eb0>\nclient     = <aiohttp.test_utils.TestClient object at 0x7691c926f670>\nhandler    = <function test_broken_connection.<locals>.handler at 0x7691c9878a60>\n\nr2e_tests/test_1.py:2487: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/test_utils.py:323: in _request\n    resp = await self._session.request(method, self.make_url(path), **kwargs)\n        kwargs     = {}\n        method     = 'GET'\n        path       = '/'\n        self       = <aiohttp.test_utils.TestClient object at 0x7691c926f670>\naiohttp/client.py:634: in _request\n    await resp.start(conn)\n        all_cookies = <SimpleCookie: >\n        allow_redirects = True\n        auth       = None\n        auth_from_url = None\n        auto_decompress = True\n        chunked    = None\n        compress   = None\n        conn       = Connection<ConnectionKey(host='127.0.0.1', port=45241, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        cookies    = None\n        data       = None\n        expect100  = False\n        handle     = None\n        headers    = <CIMultiDict()>\n        history    = []\n        json       = None\n        max_field_size = 8190\n        max_line_size = 8190\n        max_redirects = 10\n        method     = 'GET'\n        params     = {}\n        proxy      = None\n        proxy_auth = None\n        proxy_headers = <CIMultiDict()>\n        raise_for_status = None\n        read_bufsize = 65536\n        read_until_eof = True\n        real_timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        redirects  = 0\n        req        = <aiohttp.client_reqrep.ClientRequest object at 0x7691c92b70a0>\n        resp       = <ClientResponse(http://127.0.0.1:45241/) [None None]>\nNone\n\n        retry_persistent_connection = False\n        self       = <aiohttp.client.ClientSession object at 0x7691ca0c0ac0>\n        server_hostname = None\n        skip_auto_headers = None\n        skip_headers = set()\n        ssl        = True\n        str_or_url = URL('http://127.0.0.1:45241/')\n        timeout    = <_SENTINEL.sentinel: 1>\n        timer      = <aiohttp.helpers.TimerContext object at 0x7691c92b7fa0>\n        tm         = <aiohttp.helpers.TimeoutHandle object at 0x7691c926faf0>\n        trace_request_ctx = None\n        traces     = []\n        url        = URL('http://127.0.0.1:45241/')\n        version    = HttpVersion(major=1, minor=1)\naiohttp/client_reqrep.py:931: in start\n    message, payload = await protocol.read()  # type: ignore[union-attr]\n        connection = Connection<ConnectionKey(host='127.0.0.1', port=45241, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        protocol   = <aiohttp.client_proto.ResponseHandler object at 0x7691c9508580>\n        self       = <ClientResponse(http://127.0.0.1:45241/) [None None]>\nNone\n\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <aiohttp.client_proto.ResponseHandler object at 0x7691c9508580>\n\n    async def read(self) -> _SizedT:\n        if not self._buffer and not self._eof:\n            assert not self._waiter\n            self._waiter = self._loop.create_future()\n            try:\n>               await self._waiter\nE               aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected\n\nself       = <aiohttp.client_proto.ResponseHandler object at 0x7691c9508580>\n\naiohttp/streams.py:631: ServerDisconnectedError\n_________________________ test_rejected_upload[pyloop] _________________________\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9db3550>\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-616/test_rejected_upload_pyloop_0')\n\n    @pytest.mark.xfail(raises=asyncio.TimeoutError, reason=\"#7599\")\n    async def test_rejected_upload(\n        aiohttp_client: AiohttpClient, tmp_path: pathlib.Path\n    ) -> None:\n        async def ok_handler(request: web.Request) -> web.Response:\n            return web.Response()\n    \n        async def not_ok_handler(request: web.Request) -> NoReturn:\n            raise web.HTTPBadRequest()\n    \n        app = web.Application()\n        app.router.add_get(\"/ok\", ok_handler)\n        app.router.add_post(\"/not_ok\", not_ok_handler)\n        client = await aiohttp_client(app)\n    \n        file_size_bytes = 1024 * 1024\n        file_path = tmp_path / \"uploaded.txt\"\n        file_path.write_text(\"0\" * file_size_bytes, encoding=\"utf8\")\n    \n        with open(file_path, \"rb\") as file:\n            data = {\"file\": file}\n            async with await client.post(\"/not_ok\", data=data) as resp_not_ok:\n                assert 400 == resp_not_ok.status\n    \n>       async with await client.get(\n            \"/ok\", timeout=aiohttp.ClientTimeout(total=0.01)\n        ) as resp_ok:\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9db3550>\napp        = <Application 0x7691c99d3300>\nclient     = <aiohttp.test_utils.TestClient object at 0x7691c927a4c0>\ndata       = {'file': <_io.BufferedReader name='/tmp/pytest-of-gcpuser/pytest-616/test_rejected_upload_pyloop_0/uploaded.txt'>}\nfile       = <_io.BufferedReader name='/tmp/pytest-of-gcpuser/pytest-616/test_rejected_upload_pyloop_0/uploaded.txt'>\nfile_path  = PosixPath('/tmp/pytest-of-gcpuser/pytest-616/test_rejected_upload_pyloop_0/uploaded.txt')\nfile_size_bytes = 1048576\nnot_ok_handler = <function test_rejected_upload.<locals>.not_ok_handler at 0x7691c9e2c9d0>\nok_handler = <function test_rejected_upload.<locals>.ok_handler at 0x7691c9e2c940>\nresp_not_ok = <ClientResponse(http://127.0.0.1:42497/not_ok) [400 Bad Request]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '16', 'Date': 'Thu, 02 Jan 2025 05:41:09 GMT', 'Server': 'Python/3.9 aiohttp/4.0.0a2.dev0')>\n\ntmp_path   = PosixPath('/tmp/pytest-of-gcpuser/pytest-616/test_rejected_upload_pyloop_0')\n\nr2e_tests/test_1.py:3909: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/test_utils.py:323: in _request\n    resp = await self._session.request(method, self.make_url(path), **kwargs)\n        kwargs     = {'timeout': ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)}\n        method     = 'GET'\n        path       = '/ok'\n        self       = <aiohttp.test_utils.TestClient object at 0x7691c927a4c0>\naiohttp/client.py:634: in _request\n    await resp.start(conn)\n        all_cookies = <SimpleCookie: >\n        allow_redirects = True\n        auth       = None\n        auth_from_url = None\n        auto_decompress = True\n        chunked    = None\n        compress   = None\n        conn       = Connection<ConnectionKey(host='127.0.0.1', port=42497, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        cookies    = None\n        data       = None\n        expect100  = False\n        handle     = None\n        headers    = <CIMultiDict()>\n        history    = []\n        json       = None\n        max_field_size = 8190\n        max_line_size = 8190\n        max_redirects = 10\n        method     = 'GET'\n        params     = {}\n        proxy      = None\n        proxy_auth = None\n        proxy_headers = <CIMultiDict()>\n        raise_for_status = None\n        read_bufsize = 65536\n        read_until_eof = True\n        real_timeout = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        redirects  = 0\n        req        = <aiohttp.client_reqrep.ClientRequest object at 0x7691c9ebe670>\n        resp       = <ClientResponse(http://127.0.0.1:42497/ok) [None None]>\nNone\n\n        retry_persistent_connection = True\n        self       = <aiohttp.client.ClientSession object at 0x7691ca040ba0>\n        server_hostname = None\n        skip_auto_headers = None\n        skip_headers = set()\n        ssl        = True\n        str_or_url = URL('http://127.0.0.1:42497/ok')\n        timeout    = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        timer      = <aiohttp.helpers.TimerContext object at 0x7691c927a3a0>\n        tm         = <aiohttp.helpers.TimeoutHandle object at 0x7691c927ab80>\n        trace_request_ctx = None\n        traces     = []\n        url        = URL('http://127.0.0.1:42497/ok')\n        version    = HttpVersion(major=1, minor=1)\naiohttp/client_reqrep.py:946: in start\n    self._continue = None\n        connection = Connection<ConnectionKey(host='127.0.0.1', port=42497, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        protocol   = <aiohttp.client_proto.ResponseHandler object at 0x7691c9508640>\n        self       = <ClientResponse(http://127.0.0.1:42497/ok) [None None]>\nNone\n\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <aiohttp.helpers.TimerContext object at 0x7691c927a3a0>\nexc_type = <class 'asyncio.exceptions.CancelledError'>\nexc_val = CancelledError(), exc_tb = <traceback object at 0x7691c96b64c0>\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> Optional[bool]:\n        if self._tasks:\n            self._tasks.pop()  # type: ignore[unused-awaitable]\n    \n        if exc_type is asyncio.CancelledError and self._cancelled:\n>           raise asyncio.TimeoutError from None\nE           asyncio.exceptions.TimeoutError\n\nexc_tb     = <traceback object at 0x7691c96b64c0>\nexc_type   = <class 'asyncio.exceptions.CancelledError'>\nexc_val    = CancelledError()\nself       = <aiohttp.helpers.TimerContext object at 0x7691c927a3a0>\n\naiohttp/helpers.py:724: TimeoutError\n_____________________ test_header_too_large_error[pyloop] ______________________\n\nself = <aiohttp.client_proto.ResponseHandler object at 0x7691c9e395e0>\ndata = b'HTTP/1.1 200 OK\\r\\nVeryLargeHeader: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxx\\r\\nContent-Length: 0\\r\\nDate: Thu, 02 Jan 2025 05:41:09 GMT\\r\\nServer: Python/3.9 aiohttp/4.0.0a2.dev0\\r\\n\\r\\n'\n\n    def data_received(self, data: bytes) -> None:\n        self._reschedule_timeout()\n    \n        if not data:\n            return\n    \n        # custom payload parser\n        if self._payload_parser is not None:\n            eof, tail = self._payload_parser.feed_data(data)\n            if eof:\n                self._payload = None\n                self._payload_parser = None\n    \n                if tail:\n                    self.data_received(tail)\n            return\n        else:\n            if self._upgraded or self._parser is None:\n                # i.e. websocket connection, websocket parser is not set yet\n                self._tail += data\n            else:\n                # parse http messages\n                try:\n>                   messages, upgraded, tail = self._parser.feed_data(data)\n\ndata       = b'HTTP/1.1 200 OK\\r\\nVeryLargeHeader: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxx\\r\\nContent-Length: 0\\r\\nDate: Thu, 02 Jan 2025 05:41:09 GMT\\r\\nServer: Python/3.9 aiohttp/4.0.0a2.dev0\\r\\n\\r\\n'\nself       = <aiohttp.client_proto.ResponseHandler object at 0x7691c9e395e0>\n\naiohttp/client_proto.py:277: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/_http_parser.pyx:563: in aiohttp._http_parser.HttpParser.feed_data\n    raise ex\n        ALLOWED_UPGRADES = frozenset({'websocket'})\n        BadHttpMessage = <class 'aiohttp.http_exceptions.BadHttpMessage'>\n        BadStatusLine = <class 'aiohttp.http_exceptions.BadStatusLine'>\n        ContentLengthError = <class 'aiohttp.http_exceptions.ContentLengthError'>\n        DEBUG      = False\n        HttpRequestParser = <class 'aiohttp._http_parser.HttpRequestParser'>\n        HttpResponseParser = <class 'aiohttp._http_parser.HttpResponseParser'>\n        InvalidHeader = <class 'aiohttp.http_exceptions.InvalidHeader'>\n        InvalidURLError = <class 'aiohttp.http_exceptions.InvalidURLError'>\n        LineTooLong = <class 'aiohttp.http_exceptions.LineTooLong'>\n        PayloadEncodingError = <class 'aiohttp.http_exceptions.PayloadEncodingError'>\n        RawRequestMessage = <class 'aiohttp._http_parser.RawRequestMessage'>\n        RawResponseMessage = <class 'aiohttp._http_parser.RawResponseMessage'>\n        TransferEncodingError = <class 'aiohttp.http_exceptions.TransferEncodingError'>\n        _CIMultiDict = <class 'multidict._multidict.CIMultiDict'>\n        _CIMultiDictProxy = <class 'multidict._multidict.CIMultiDictProxy'>\n        _DeflateBuffer = <class 'aiohttp.http_parser.DeflateBuffer'>\n        _EMPTY_PAYLOAD = <EmptyStreamReader>\n        _HttpVersion = <class 'aiohttp.http_writer.HttpVersion'>\n        _HttpVersion10 = HttpVersion(major=1, minor=0)\n        _HttpVersion11 = HttpVersion(major=1, minor=1)\n        _StreamReader = <class 'aiohttp.streams.StreamReader'>\n        _URL       = <class 'yarl.URL'>\n        __all__    = ('HttpRequestParser', 'HttpResponseParser', 'RawRequestMessage', 'RawResponseMessage')\n        __builtins__ = <builtins>\n        __doc__    = None\n        __file__   = '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so'\n        __loader__ = <_frozen_importlib_external.ExtensionFileLoader object at 0x7691cb8831c0>\n        __name__   = 'aiohttp._http_parser'\n        __package__ = 'aiohttp'\n        __pyx_unpickle_RawRequestMessage = <cyfunction __pyx_unpickle_RawRequestMessage at 0x7691cb7ef380>\n        __pyx_unpickle_RawResponseMessage = <cyfunction __pyx_unpickle_RawResponseMessage at 0x7691cb7ef5f0>\n        __reduce_cython__ = <cyfunction HttpResponseParser.__reduce_cython__ at 0x7691cb7ef450>\n        __setstate_cython__ = <cyfunction HttpResponseParser.__setstate_cython__ at 0x7691cb7ef520>\n        __spec__   = ModuleSpec(name='aiohttp._http_parser', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x7691cb8831c...val_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so')\n        __test__   = {}\n        hdrs       = <module 'aiohttp.hdrs' from '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/hdrs.py'>\n        i          = 45\n        set_exception = <function set_exception at 0x7691cb869670>\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n>   raise LineTooLong(\nE   aiohttp.http_exceptions.LineTooLong: 400, message:\nE     Got more than 8190 bytes (10000) when reading Header value is too long.\n\nALLOWED_UPGRADES = frozenset({'websocket'})\nBadHttpMessage = <class 'aiohttp.http_exceptions.BadHttpMessage'>\nBadStatusLine = <class 'aiohttp.http_exceptions.BadStatusLine'>\nContentLengthError = <class 'aiohttp.http_exceptions.ContentLengthError'>\nDEBUG      = False\nHttpRequestParser = <class 'aiohttp._http_parser.HttpRequestParser'>\nHttpResponseParser = <class 'aiohttp._http_parser.HttpResponseParser'>\nInvalidHeader = <class 'aiohttp.http_exceptions.InvalidHeader'>\nInvalidURLError = <class 'aiohttp.http_exceptions.InvalidURLError'>\nLineTooLong = <class 'aiohttp.http_exceptions.LineTooLong'>\nPayloadEncodingError = <class 'aiohttp.http_exceptions.PayloadEncodingError'>\nRawRequestMessage = <class 'aiohttp._http_parser.RawRequestMessage'>\nRawResponseMessage = <class 'aiohttp._http_parser.RawResponseMessage'>\nTransferEncodingError = <class 'aiohttp.http_exceptions.TransferEncodingError'>\n_CIMultiDict = <class 'multidict._multidict.CIMultiDict'>\n_CIMultiDictProxy = <class 'multidict._multidict.CIMultiDictProxy'>\n_DeflateBuffer = <class 'aiohttp.http_parser.DeflateBuffer'>\n_EMPTY_PAYLOAD = <EmptyStreamReader>\n_HttpVersion = <class 'aiohttp.http_writer.HttpVersion'>\n_HttpVersion10 = HttpVersion(major=1, minor=0)\n_HttpVersion11 = HttpVersion(major=1, minor=1)\n_StreamReader = <class 'aiohttp.streams.StreamReader'>\n_URL       = <class 'yarl.URL'>\n__all__    = ('HttpRequestParser', 'HttpResponseParser', 'RawRequestMessage', 'RawResponseMessage')\n__builtins__ = <builtins>\n__doc__    = None\n__file__   = '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so'\n__loader__ = <_frozen_importlib_external.ExtensionFileLoader object at 0x7691cb8831c0>\n__name__   = 'aiohttp._http_parser'\n__package__ = 'aiohttp'\n__pyx_unpickle_RawRequestMessage = <cyfunction __pyx_unpickle_RawRequestMessage at 0x7691cb7ef380>\n__pyx_unpickle_RawResponseMessage = <cyfunction __pyx_unpickle_RawResponseMessage at 0x7691cb7ef5f0>\n__reduce_cython__ = <cyfunction HttpResponseParser.__reduce_cython__ at 0x7691cb7ef450>\n__setstate_cython__ = <cyfunction HttpResponseParser.__setstate_cython__ at 0x7691cb7ef520>\n__spec__   = ModuleSpec(name='aiohttp._http_parser', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x7691cb8831c...val_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so')\n__test__   = {}\nhdrs       = <module 'aiohttp.hdrs' from '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/hdrs.py'>\ni          = 45\nset_exception = <function set_exception at 0x7691cb869670>\n\naiohttp/_http_parser.pyx:738: LineTooLong\n\nThe above exception was the direct cause of the following exception:\n\nself = <ClientResponse(http://127.0.0.1:34413/) [None None]>\nNone\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=34413, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n\n    async def start(self, connection: \"Connection\") -> \"ClientResponse\":\n        \"\"\"Start response processing.\"\"\"\n        self._closed = False\n        self._protocol = connection.protocol\n        self._connection = connection\n    \n        with self._timer:\n            while True:\n                # read response\n                try:\n                    protocol = self._protocol\n>                   message, payload = await protocol.read()  # type: ignore[union-attr]\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=34413, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\nprotocol   = <aiohttp.client_proto.ResponseHandler object at 0x7691c9e395e0>\nself       = <ClientResponse(http://127.0.0.1:34413/) [None None]>\nNone\n\n\naiohttp/client_reqrep.py:931: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <aiohttp.client_proto.ResponseHandler object at 0x7691c9e395e0>\n\n    async def read(self) -> _SizedT:\n        if not self._buffer and not self._eof:\n            assert not self._waiter\n            self._waiter = self._loop.create_future()\n            try:\n>               await self._waiter\nE               aiohttp.http_exceptions.HttpProcessingError: 0, message:\n\nself       = <aiohttp.client_proto.ResponseHandler object at 0x7691c9e395e0>\n\naiohttp/streams.py:631: HttpProcessingError\n\nThe above exception was the direct cause of the following exception:\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9e2c0d0>\n\n    @pytest.mark.xfail(\n        reason=\"#8395 Error message regression for large headers in 3.9.4\",\n        raises=AssertionError,\n    )\n    async def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n        \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n    \n        async def handler(_: web.Request) -> web.Response:\n            return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n    \n        app = web.Application()\n        app.add_routes([web.get(\"/\", handler)])\n        client = await aiohttp_client(app)\n    \n        with pytest.raises(\n            aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n        ) as exc_info:\n>           await client.get(\"/\")\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9e2c0d0>\napp        = <Application 0x7691c99c3300>\nclient     = <aiohttp.test_utils.TestClient object at 0x7691c9ebef70>\nexc_info   = <ExceptionInfo ClientResponseError(RequestInfo(url=URL('http://127.0.0.1:34413/'), method='GET', headers=<CIMultiDictP...deflate, br', 'User-Agent': 'Python/3.9 aiohttp/4.0.0a2.dev0')>, real_url=URL('http://127.0.0.1:34413/')), ()) tblen=4>\nhandler    = <function test_header_too_large_error.<locals>.handler at 0x7691c9e2c940>\n\nr2e_tests/test_1.py:3965: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/test_utils.py:323: in _request\n    resp = await self._session.request(method, self.make_url(path), **kwargs)\n        kwargs     = {}\n        method     = 'GET'\n        path       = '/'\n        self       = <aiohttp.test_utils.TestClient object at 0x7691c9ebef70>\naiohttp/client.py:634: in _request\n    await resp.start(conn)\n        all_cookies = <SimpleCookie: >\n        allow_redirects = True\n        auth       = None\n        auth_from_url = None\n        auto_decompress = True\n        chunked    = None\n        compress   = None\n        conn       = Connection<ConnectionKey(host='127.0.0.1', port=34413, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        cookies    = None\n        data       = None\n        expect100  = False\n        handle     = None\n        headers    = <CIMultiDict()>\n        history    = []\n        json       = None\n        max_field_size = 8190\n        max_line_size = 8190\n        max_redirects = 10\n        method     = 'GET'\n        params     = {}\n        proxy      = None\n        proxy_auth = None\n        proxy_headers = <CIMultiDict()>\n        raise_for_status = None\n        read_bufsize = 65536\n        read_until_eof = True\n        real_timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        redirects  = 0\n        req        = <aiohttp.client_reqrep.ClientRequest object at 0x7691c92cd100>\n        resp       = <ClientResponse(http://127.0.0.1:34413/) [None None]>\nNone\n\n        retry_persistent_connection = True\n        self       = <aiohttp.client.ClientSession object at 0x7691ca040e40>\n        server_hostname = None\n        skip_auto_headers = None\n        skip_headers = set()\n        ssl        = True\n        str_or_url = URL('http://127.0.0.1:34413/')\n        timeout    = <_SENTINEL.sentinel: 1>\n        timer      = <aiohttp.helpers.TimerContext object at 0x7691c92cdd90>\n        tm         = <aiohttp.helpers.TimeoutHandle object at 0x7691c92cd220>\n        trace_request_ctx = None\n        traces     = []\n        url        = URL('http://127.0.0.1:34413/')\n        version    = HttpVersion(major=1, minor=1)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <ClientResponse(http://127.0.0.1:34413/) [None None]>\nNone\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=34413, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n\n    async def start(self, connection: \"Connection\") -> \"ClientResponse\":\n        \"\"\"Start response processing.\"\"\"\n        self._closed = False\n        self._protocol = connection.protocol\n        self._connection = connection\n    \n        with self._timer:\n            while True:\n                # read response\n                try:\n                    protocol = self._protocol\n                    message, payload = await protocol.read()  # type: ignore[union-attr]\n                except http.HttpProcessingError as exc:\n>                   raise ClientResponseError(\n                        self.request_info,\n                        self.history,\n                        status=exc.code,\n                        message=exc.message,\n                        headers=exc.headers,\n                    ) from exc\nE                   aiohttp.client_exceptions.ClientResponseError: 0, message='', url='http://127.0.0.1:34413/'\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=34413, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\nprotocol   = <aiohttp.client_proto.ResponseHandler object at 0x7691c9e395e0>\nself       = <ClientResponse(http://127.0.0.1:34413/) [None None]>\nNone\n\n\naiohttp/client_reqrep.py:933: ClientResponseError\n\nDuring handling of the above exception, another exception occurred:\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9e2c0d0>\n\n    @pytest.mark.xfail(\n        reason=\"#8395 Error message regression for large headers in 3.9.4\",\n        raises=AssertionError,\n    )\n    async def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n        \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n    \n        async def handler(_: web.Request) -> web.Response:\n            return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n    \n        app = web.Application()\n        app.add_routes([web.get(\"/\", handler)])\n        client = await aiohttp_client(app)\n    \n        with pytest.raises(\n            aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n        ) as exc_info:\n>           await client.get(\"/\")\nE           AssertionError: Regex pattern did not match.\nE            Regex: 'Got more than 8190 bytes*'\nE            Input: \"0, message='', url='http://127.0.0.1:34413/'\"\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x7691c9e2c0d0>\napp        = <Application 0x7691c99c3300>\nclient     = <aiohttp.test_utils.TestClient object at 0x7691c9ebef70>\nexc_info   = <ExceptionInfo ClientResponseError(RequestInfo(url=URL('http://127.0.0.1:34413/'), method='GET', headers=<CIMultiDictP...deflate, br', 'User-Agent': 'Python/3.9 aiohttp/4.0.0a2.dev0')>, real_url=URL('http://127.0.0.1:34413/')), ()) tblen=4>\nhandler    = <function test_header_too_large_error.<locals>.handler at 0x7691c9e2c940>\n\nr2e_tests/test_1.py:3965: AssertionError\n==================================== PASSES ====================================\n______________________ test_keepalive_timeout_sync_sleep _______________________\n------------------------------ Captured log call -------------------------------\nERROR    asyncio:base_events.py:1753 Task exception was never retrieved\nfuture: <Task finished name='Task-116' coro=<RequestHandler.start() done, defined at /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_protocol.py:501> exception=AssertionError()>\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_protocol.py\", line 544, in start\n    request = self._request_factory(message, payload, self, writer, handler)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_runner.py\", line 425, in _make_request\n    return _cls(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_request.py\", line 840, in __init__\n    super().__init__(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_request.py\", line 198, in __init__\n    assert transport is not None\nAssertionError\n---------------------------- Captured log teardown -----------------------------\nERROR    asyncio:base_events.py:1753 Unclosed client session\nclient_session: <aiohttp.client.ClientSession object at 0x7691ca084ba0>\n____________________ test_aiohttp_request_coroutine[pyloop] ____________________\n------------------------------ Captured log call -------------------------------\nERROR    asyncio:base_events.py:1753 Unclosed client session\nclient_session: <aiohttp.client.ClientSession object at 0x7691ca040d60>\n\n---------- coverage: platform linux, python 3.9.21-final-0 -----------\nName                                     Stmts   Miss Branch BrPart  Cover\n--------------------------------------------------------------------------\naiohttp/__init__.py                         26      8      2      1    68%\naiohttp/abc.py                              97      2      0      0    98%\naiohttp/base_protocol.py                    67     28     22      5    49%\naiohttp/client.py                          520    105    186     16    77%\naiohttp/client_exceptions.py               139     21     14      4    84%\naiohttp/client_proto.py                    168     30     58     11    78%\naiohttp/client_reqrep.py                   659    114    280     56    78%\naiohttp/client_ws.py                       264    211     82      1    16%\naiohttp/compression_utils.py                70     15     14      1    71%\naiohttp/connector.py                       720    250    301     52    59%\naiohttp/cookiejar.py                       253     60    120     24    73%\naiohttp/formdata.py                         86      7     38      5    90%\naiohttp/hdrs.py                             90      0      0      0   100%\naiohttp/helpers.py                         550    188    200     35    61%\naiohttp/http.py                              8      0      0      0   100%\naiohttp/http_exceptions.py                  48      8      2      1    82%\naiohttp/http_parser.py                     492    339    206     11    24%\naiohttp/http_websocket.py                  382    285    154      0    18%\naiohttp/http_writer.py                     118     12     50      5    86%\naiohttp/locks.py                            24     10      4      0    50%\naiohttp/log.py                               7      0      0      0   100%\naiohttp/multipart.py                       625    293    268     49    46%\naiohttp/payload.py                         237     22     58     12    86%\naiohttp/pytest_plugin.py                   160     44     42      7    70%\naiohttp/resolver.py                         61     24     18      3    53%\naiohttp/streams.py                         395    113    142     18    67%\naiohttp/tcp_helpers.py                      19      2      6      3    80%\naiohttp/test_utils.py                      304    103     54     13    61%\naiohttp/tracing.py                         193     17     32      0    92%\naiohttp/typedefs.py                         23      0      0      0   100%\naiohttp/web.py                             124     86     52      0    23%\naiohttp/web_app.py                         233     80     50     11    59%\naiohttp/web_exceptions.py                  214     28     26      7    83%\naiohttp/web_fileresponse.py                160    126     52      0    18%\naiohttp/web_log.py                         102     37     20      1    59%\naiohttp/web_middlewares.py                  54     38     20      0    22%\naiohttp/web_protocol.py                    363     95    155     46    67%\naiohttp/web_request.py                     440    173    136     23    55%\naiohttp/web_response.py                    435    101    192     38    71%\naiohttp/web_routedef.py                    100     37     10      1    62%\naiohttp/web_runner.py                      222     60     40     13    68%\naiohttp/web_server.py                       49      6     14      2    84%\naiohttp/web_urldispatcher.py               721    317    153     21    52%\naiohttp/web_ws.py                          383    311    132      1    15%\naiohttp/worker.py                          123    123     30      0     0%\ntests/conftest.py                          130    130     16      0     0%\ntests/test_base_protocol.py                198    198      2      0     0%\ntests/test_circular_imports.py              29     29     13      0     0%\ntests/test_classbasedview.py                39     39      0      0     0%\ntests/test_client_connection.py             93     93      2      0     0%\ntests/test_client_exceptions.py            182    182     14      0     0%\ntests/test_client_fingerprint.py            24     24      0      0     0%\ntests/test_client_functional.py           2512   2512     72      0     0%\ntests/test_client_proto.py                 103    103      0      0     0%\ntests/test_client_request.py               780    780     18      0     0%\ntests/test_client_response.py              488    488      4      0     0%\ntests/test_client_session.py               533    533     29      0     0%\ntests/test_client_ws.py                    487    487      2      0     0%\ntests/test_client_ws_functional.py         782    782     22      0     0%\ntests/test_connector.py                   1673   1673     78      0     0%\ntests/test_cookiejar.py                    358    358     20      0     0%\ntests/test_flowcontrol_streams.py           98     98      0      0     0%\ntests/test_formdata.py                      81     81      4      0     0%\ntests/test_helpers.py                      569    569     22      0     0%\ntests/test_http_exceptions.py              110    110     10      0     0%\ntests/test_http_parser.py                 1087   1087     44      0     0%\ntests/test_http_writer.py                  178    178     10      0     0%\ntests/test_imports.py                       34     34      6      0     0%\ntests/test_locks.py                         40     40      0      0     0%\ntests/test_loop.py                          36     36      0      0     0%\ntests/test_multipart.py                    869    869     34      0     0%\ntests/test_multipart_helpers.py            446    446      0      0     0%\ntests/test_payload.py                       80     80      0      0     0%\ntests/test_proxy.py                        335    335      0      0     0%\ntests/test_proxy_functional.py             465    465     20      0     0%\ntests/test_pytest_plugin.py                 47     47      0      0     0%\ntests/test_resolver.py                     177    177     18      0     0%\ntests/test_route_def.py                    191    191      0      0     0%\ntests/test_run_app.py                      576    576     30      0     0%\ntests/test_streams.py                     1060   1060     38      0     0%\ntests/test_tcp_helpers.py                   52     52      2      0     0%\ntests/test_test_utils.py                   237    237      6      0     0%\ntests/test_tracing.py                       49     49      0      0     0%\ntests/test_urldispatch.py                  854    854     24      0     0%\ntests/test_web_app.py                      383    383      6      0     0%\ntests/test_web_cli.py                       76     76      0      0     0%\ntests/test_web_exceptions.py               274    274     30      0     0%\ntests/test_web_functional.py              1503   1503     30      0     0%\ntests/test_web_log.py                      143    143      2      0     0%\ntests/test_web_middleware.py               230    230      2      0     0%\ntests/test_web_request.py                  533    533      8      0     0%\ntests/test_web_request_handler.py           42     42      0      0     0%\ntests/test_web_response.py                 834    834      6      0     0%\ntests/test_web_runner.py                   180    180      4      0     0%\ntests/test_web_sendfile.py                  85     85      0      0     0%\ntests/test_web_sendfile_functional.py      656    656     18      0     0%\ntests/test_web_server.py                   177    177      0      0     0%\ntests/test_web_urldispatcher.py            504    504     24      0     0%\ntests/test_web_websocket.py                383    383      8      0     0%\ntests/test_web_websocket_functional.py     799    799     32      0     0%\ntests/test_websocket_handshake.py          153    153     12      0     0%\ntests/test_websocket_parser.py             290    290     12      0     0%\ntests/test_websocket_writer.py              96     96      6      0     0%\ntests/test_worker.py                       190    190      2      0     0%\n--------------------------------------------------------------------------\nTOTAL                                    34141  27542   4197    497    21%\n\n============================= slowest 10 durations =============================\n2.01s call     r2e_tests/test_1.py::test_read_timeout_between_chunks[pyloop]\n2.01s call     r2e_tests/test_1.py::test_set_cookies_max_age[pyloop]\n1.00s call     r2e_tests/test_1.py::test_readline_error_on_conn_close[pyloop]\n1.00s call     r2e_tests/test_1.py::test_timeout_on_reading_data[pyloop]\n0.51s call     r2e_tests/test_1.py::test_timeout_with_full_buffer[pyloop]\n0.50s call     r2e_tests/test_1.py::test_no_error_on_conn_close_if_eof[pyloop]\n0.50s call     r2e_tests/test_1.py::test_read_timeout_on_write[pyloop]\n0.21s call     r2e_tests/test_1.py::test_read_timeout_closes_connection[pyloop]\n0.20s call     r2e_tests/test_1.py::test_read_timeout_on_reading_chunks[pyloop]\n0.10s call     r2e_tests/test_1.py::test_read_timeout_on_prepared_response[pyloop]\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::test_keepalive_two_requests_success[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_after_head_requests_success[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-101]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-204]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-304]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-101]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-204]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-304]\nPASSED r2e_tests/test_1.py::test_keepalive_response_released[pyloop]\nPASSED r2e_tests/test_1.py::test_upgrade_connection_not_released_after_read[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_server_force_close_connection[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_timeout_async_sleep\nPASSED r2e_tests/test_1.py::test_keepalive_timeout_sync_sleep\nPASSED r2e_tests/test_1.py::test_release_early[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_304[pyloop]\nPASSED r2e_tests/test_1.py::test_stream_request_on_server_eof[pyloop]\nPASSED r2e_tests/test_1.py::test_stream_request_on_server_eof_nested[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_304_WITH_BODY[pyloop]\nPASSED r2e_tests/test_1.py::test_auto_header_user_agent[pyloop]\nPASSED r2e_tests/test_1.py::test_skip_auto_headers_user_agent[pyloop]\nPASSED r2e_tests/test_1.py::test_skip_default_auto_headers_user_agent[pyloop]\nPASSED r2e_tests/test_1.py::test_skip_auto_headers_content_type[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_bytesio[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_with_bytesio_file[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_stringio[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_textio_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_zipfile_filelike[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_tarfile_filelike[pyloop]\nPASSED r2e_tests/test_1.py::test_ssl_client[pyloop]\nPASSED r2e_tests/test_1.py::test_tcp_connector_fingerprint_ok[pyloop]\nPASSED r2e_tests/test_1.py::test_tcp_connector_fingerprint_fail[pyloop]\nPASSED r2e_tests/test_1.py::test_format_task_get[pyloop]\nPASSED r2e_tests/test_1.py::test_str_params[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_params_on_redirect[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_fragment_on_redirect[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_fragment[pyloop]\nPASSED r2e_tests/test_1.py::test_history[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_closed_by_server[pyloop]\nPASSED r2e_tests/test_1.py::test_wait_for[pyloop]\nPASSED r2e_tests/test_1.py::test_raw_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_host_header_first[pyloop]\nPASSED r2e_tests/test_1.py::test_empty_header_values[pyloop]\nPASSED r2e_tests/test_1.py::test_204_with_gzipped_content_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_reading_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_conn_reading_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_session_read_timeout[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_between_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_on_reading_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_on_write[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_reading_data[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_none[pyloop]\nPASSED r2e_tests/test_1.py::test_readline_error_on_conn_close[pyloop]\nPASSED r2e_tests/test_1.py::test_no_error_on_conn_close_if_eof[pyloop]\nPASSED r2e_tests/test_1.py::test_error_not_overwrote_on_conn_close[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_OK_METHOD[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_OK_METHOD_connector[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_GET[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_HEAD[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_NON_HTTP[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST_with_content_length_hdr[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_307_REDIRECT_POST[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_308_PERMANENT_REDIRECT_POST[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_max_redirects[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_GET_WITH_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_GET_WITH_MultiDict_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_GET_WITH_MIXED_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_with_explicit_formdata[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_with_charset[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_formdats_with_charset[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_with_charset_post[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_MultiDict[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_DEFLATE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_DEFLATE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_bytes[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_bytes_too_large[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_STR[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_STR_SIMPLE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_LIST[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_CT[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_SINGLE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_SINGLE_content_disposition[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_SINGLE_BINARY[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_IO[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_IO_WITH_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_WITH_DATA[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_STREAM_DATA[pyloop]\nPASSED r2e_tests/test_1.py::test_json[pyloop]\nPASSED r2e_tests/test_1.py::test_json_custom[pyloop]\nPASSED r2e_tests/test_1.py::test_expect_continue[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_deflate[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_deflate_nochunk[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_gzip[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_gzip_write_by_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_gzip_nochunk[pyloop]\nPASSED r2e_tests/test_1.py::test_bad_payload_compression[pyloop]\nPASSED r2e_tests/test_1.py::test_bad_payload_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_no_payload_304_with_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_head_request_with_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_no_payload_200_with_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_bad_payload_content_length[pyloop]\nPASSED r2e_tests/test_1.py::test_payload_content_length_by_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_chunked[pyloop]\nPASSED r2e_tests/test_1.py::test_shortcuts[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies_per_request[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies_redirect[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies_on_empty_session_jar[pyloop]\nPASSED r2e_tests/test_1.py::test_morsel_with_attributes[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies_expired[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies_max_age[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies_max_age_overflow[pyloop]\nPASSED r2e_tests/test_1.py::test_request_conn_error\nPASSED r2e_tests/test_1.py::test_broken_connection_2[pyloop]\nPASSED r2e_tests/test_1.py::test_custom_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_redirect_to_absolute_url[pyloop]\nPASSED r2e_tests/test_1.py::test_redirect_without_location_header[pyloop]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http://:/-http://:/-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http:/-http:///-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http:/example.com-http:///example.com-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http:///example.com-http:///example.com-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[call:+380123456789-call:\\\\+380123456789-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[skype:handle-skype:handle-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[slack://instance/room-slack://instance/room-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[steam:code-steam:code-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[twitter://handle-twitter://handle-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/-http:///-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/-http:///-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-200-True]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-201-True]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-301-True]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-400-False]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-403-False]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-500-False]\nPASSED r2e_tests/test_1.py::test_raise_for_status[pyloop]\nPASSED r2e_tests/test_1.py::test_raise_for_status_per_request[pyloop]\nPASSED r2e_tests/test_1.py::test_raise_for_status_disable_per_request[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_default[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_disabled[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_enabled[pyloop]\nPASSED r2e_tests/test_1.py::test_session_raise_for_status_coro[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_coro[pyloop]\nPASSED r2e_tests/test_1.py::test_invalid_idna\nPASSED r2e_tests/test_1.py::test_creds_in_auth_and_url\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts]\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-http -> https]\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-https -> http]\nPASSED r2e_tests/test_1.py::test_auth_persist_on_redirect_to_other_host_with_global_auth[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url[pyloop]\nPASSED r2e_tests/test_1.py::test_async_with_session\nPASSED r2e_tests/test_1.py::test_session_close_awaitable\nPASSED r2e_tests/test_1.py::test_close_resp_on_error_async_with_session[pyloop]\nPASSED r2e_tests/test_1.py::test_release_resp_on_normal_exit_from_cm[pyloop]\nPASSED r2e_tests/test_1.py::test_non_close_detached_session_on_error_cm[pyloop]\nPASSED r2e_tests/test_1.py::test_close_detached_session_on_non_existing_addr\nPASSED r2e_tests/test_1.py::test_aiohttp_request_context_manager[pyloop]\nPASSED r2e_tests/test_1.py::test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop]\nPASSED r2e_tests/test_1.py::test_aiohttp_request_ctx_manager_not_found\nPASSED r2e_tests/test_1.py::test_aiohttp_request_coroutine[pyloop]\nPASSED r2e_tests/test_1.py::test_yield_from_in_session_request[pyloop]\nPASSED r2e_tests/test_1.py::test_close_context_manager[pyloop]\nPASSED r2e_tests/test_1.py::test_session_auth[pyloop]\nPASSED r2e_tests/test_1.py::test_session_auth_override[pyloop]\nPASSED r2e_tests/test_1.py::test_session_auth_header_conflict[pyloop]\nPASSED r2e_tests/test_1.py::test_session_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_session_headers_merge[pyloop]\nPASSED r2e_tests/test_1.py::test_multidict_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_request_conn_closed[pyloop]\nPASSED r2e_tests/test_1.py::test_dont_close_explicit_connector[pyloop]\nPASSED r2e_tests/test_1.py::test_server_close_keepalive_connection\nPASSED r2e_tests/test_1.py::test_handle_keepalive_on_closed_connection\nPASSED r2e_tests/test_1.py::test_error_in_performing_request[pyloop]\nPASSED r2e_tests/test_1.py::test_await_after_cancelling[pyloop]\nPASSED r2e_tests/test_1.py::test_async_payload_generator[pyloop]\nPASSED r2e_tests/test_1.py::test_read_from_closed_response[pyloop]\nPASSED r2e_tests/test_1.py::test_read_from_closed_response2[pyloop]\nPASSED r2e_tests/test_1.py::test_read_from_closed_content[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout[pyloop]\nPASSED r2e_tests/test_1.py::test_socket_timeout[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_closes_connection[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_on_prepared_response[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_with_full_buffer[pyloop]\nPASSED r2e_tests/test_1.py::test_read_bufsize_session_default[pyloop]\nPASSED r2e_tests/test_1.py::test_read_bufsize_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_http_empty_data_text[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_session_default[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_session_default_fail[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_session_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_request_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_session_default[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_session_default_fail[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_session_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_request_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_request_with_wrong_ssl_type[pyloop]\nPASSED r2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-42-TypeError]\nPASSED r2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-InvalidUrl-InvalidURL]\nPASSED r2e_tests/test_1.py::test_raise_for_status_is_none[pyloop]\nPASSED r2e_tests/test_1.py::test_exception_when_read_outside_of_session[pyloop]\nXFAIL r2e_tests/test_1.py::test_broken_connection[pyloop]\nXFAIL r2e_tests/test_1.py::test_rejected_upload[pyloop] - #7599\nXFAIL r2e_tests/test_1.py::test_header_too_large_error[pyloop] - #8395 Error message regression for large headers in 3.9.4\n======================= 223 passed, 3 xfailed in 18.83s ========================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.9.21, pytest-8.1.1, pluggy-1.5.0 -- /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/.venv/bin/python\ncachedir: .pytest_cache\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4\nconfigfile: setup.cfg\nplugins: cov-5.0.0, mock-3.14.0, asyncio-0.23.8\nasyncio: mode=strict\ncollecting ... collected 226 items\n\nr2e_tests/test_1.py::test_keepalive_two_requests_success[pyloop] PASSED  [  0%]\nr2e_tests/test_1.py::test_keepalive_after_head_requests_success[pyloop] PASSED [  0%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-101] PASSED [  1%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-204] PASSED [  1%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-304] PASSED [  2%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-101] PASSED [  2%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-204] PASSED [  3%]\nr2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-304] PASSED [  3%]\nr2e_tests/test_1.py::test_keepalive_response_released[pyloop] PASSED     [  3%]\nr2e_tests/test_1.py::test_upgrade_connection_not_released_after_read[pyloop] PASSED [  4%]\nr2e_tests/test_1.py::test_keepalive_server_force_close_connection[pyloop] PASSED [  4%]\nr2e_tests/test_1.py::test_keepalive_timeout_async_sleep PASSED           [  5%]\nr2e_tests/test_1.py::test_keepalive_timeout_sync_sleep PASSED            [  5%]\nr2e_tests/test_1.py::test_release_early[pyloop] PASSED                   [  6%]\nr2e_tests/test_1.py::test_HTTP_304[pyloop] PASSED                        [  6%]\nr2e_tests/test_1.py::test_stream_request_on_server_eof[pyloop] PASSED    [  7%]\nr2e_tests/test_1.py::test_stream_request_on_server_eof_nested[pyloop] PASSED [  7%]\nr2e_tests/test_1.py::test_HTTP_304_WITH_BODY[pyloop] PASSED              [  7%]\nr2e_tests/test_1.py::test_auto_header_user_agent[pyloop] PASSED          [  8%]\nr2e_tests/test_1.py::test_skip_auto_headers_user_agent[pyloop] PASSED    [  8%]\nr2e_tests/test_1.py::test_skip_default_auto_headers_user_agent[pyloop] PASSED [  9%]\nr2e_tests/test_1.py::test_skip_auto_headers_content_type[pyloop] PASSED  [  9%]\nr2e_tests/test_1.py::test_post_data_bytesio[pyloop] PASSED               [ 10%]\nr2e_tests/test_1.py::test_post_data_with_bytesio_file[pyloop] PASSED     [ 10%]\nr2e_tests/test_1.py::test_post_data_stringio[pyloop] PASSED              [ 11%]\nr2e_tests/test_1.py::test_post_data_textio_encoding[pyloop] PASSED       [ 11%]\nr2e_tests/test_1.py::test_post_data_zipfile_filelike[pyloop] PASSED      [ 11%]\nr2e_tests/test_1.py::test_post_data_tarfile_filelike[pyloop] PASSED      [ 12%]\nr2e_tests/test_1.py::test_ssl_client[pyloop] PASSED                      [ 12%]\nr2e_tests/test_1.py::test_tcp_connector_fingerprint_ok[pyloop] PASSED    [ 13%]\nr2e_tests/test_1.py::test_tcp_connector_fingerprint_fail[pyloop] PASSED  [ 13%]\nr2e_tests/test_1.py::test_format_task_get[pyloop] PASSED                 [ 14%]\nr2e_tests/test_1.py::test_str_params[pyloop] PASSED                      [ 14%]\nr2e_tests/test_1.py::test_drop_params_on_redirect[pyloop] PASSED         [ 15%]\nr2e_tests/test_1.py::test_drop_fragment_on_redirect[pyloop] PASSED       [ 15%]\nr2e_tests/test_1.py::test_drop_fragment[pyloop] PASSED                   [ 15%]\nr2e_tests/test_1.py::test_history[pyloop] PASSED                         [ 16%]\nr2e_tests/test_1.py::test_keepalive_closed_by_server[pyloop] PASSED      [ 16%]\nr2e_tests/test_1.py::test_wait_for[pyloop] PASSED                        [ 17%]\nr2e_tests/test_1.py::test_raw_headers[pyloop] PASSED                     [ 17%]\nr2e_tests/test_1.py::test_host_header_first[pyloop] PASSED               [ 18%]\nr2e_tests/test_1.py::test_empty_header_values[pyloop] PASSED             [ 18%]\nr2e_tests/test_1.py::test_204_with_gzipped_content_encoding[pyloop] PASSED [ 19%]\nr2e_tests/test_1.py::test_timeout_on_reading_headers[pyloop] PASSED      [ 19%]\nr2e_tests/test_1.py::test_timeout_on_conn_reading_headers[pyloop] PASSED [ 19%]\nr2e_tests/test_1.py::test_timeout_on_session_read_timeout[pyloop] PASSED [ 20%]\nr2e_tests/test_1.py::test_read_timeout_between_chunks[pyloop] PASSED     [ 20%]\nr2e_tests/test_1.py::test_read_timeout_on_reading_chunks[pyloop] PASSED  [ 21%]\nr2e_tests/test_1.py::test_read_timeout_on_write[pyloop] PASSED           [ 21%]\nr2e_tests/test_1.py::test_timeout_on_reading_data[pyloop] PASSED         [ 22%]\nr2e_tests/test_1.py::test_timeout_none[pyloop] PASSED                    [ 22%]\nr2e_tests/test_1.py::test_readline_error_on_conn_close[pyloop] PASSED    [ 23%]\nr2e_tests/test_1.py::test_no_error_on_conn_close_if_eof[pyloop] PASSED   [ 23%]\nr2e_tests/test_1.py::test_error_not_overwrote_on_conn_close[pyloop] PASSED [ 23%]\nr2e_tests/test_1.py::test_HTTP_200_OK_METHOD[pyloop] PASSED              [ 24%]\nr2e_tests/test_1.py::test_HTTP_200_OK_METHOD_connector[pyloop] PASSED    [ 24%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_GET[pyloop] PASSED           [ 25%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_HEAD[pyloop] PASSED          [ 25%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_NON_HTTP[pyloop] PASSED      [ 26%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST[pyloop] PASSED          [ 26%]\nr2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST_with_content_length_hdr[pyloop] PASSED [ 26%]\nr2e_tests/test_1.py::test_HTTP_307_REDIRECT_POST[pyloop] PASSED          [ 27%]\nr2e_tests/test_1.py::test_HTTP_308_PERMANENT_REDIRECT_POST[pyloop] PASSED [ 27%]\nr2e_tests/test_1.py::test_HTTP_302_max_redirects[pyloop] PASSED          [ 28%]\nr2e_tests/test_1.py::test_HTTP_200_GET_WITH_PARAMS[pyloop] PASSED        [ 28%]\nr2e_tests/test_1.py::test_HTTP_200_GET_WITH_MultiDict_PARAMS[pyloop] PASSED [ 29%]\nr2e_tests/test_1.py::test_HTTP_200_GET_WITH_MIXED_PARAMS[pyloop] PASSED  [ 29%]\nr2e_tests/test_1.py::test_POST_DATA[pyloop] PASSED                       [ 30%]\nr2e_tests/test_1.py::test_POST_DATA_with_explicit_formdata[pyloop] PASSED [ 30%]\nr2e_tests/test_1.py::test_POST_DATA_with_charset[pyloop] PASSED          [ 30%]\nr2e_tests/test_1.py::test_POST_DATA_formdats_with_charset[pyloop] PASSED [ 31%]\nr2e_tests/test_1.py::test_POST_DATA_with_charset_post[pyloop] PASSED     [ 31%]\nr2e_tests/test_1.py::test_POST_MultiDict[pyloop] PASSED                  [ 32%]\nr2e_tests/test_1.py::test_POST_DATA_DEFLATE[pyloop] PASSED               [ 32%]\nr2e_tests/test_1.py::test_POST_FILES[pyloop] PASSED                      [ 33%]\nr2e_tests/test_1.py::test_POST_FILES_DEFLATE[pyloop] PASSED              [ 33%]\nr2e_tests/test_1.py::test_POST_bytes[pyloop] PASSED                      [ 34%]\nr2e_tests/test_1.py::test_POST_bytes_too_large[pyloop] PASSED            [ 34%]\nr2e_tests/test_1.py::test_POST_FILES_STR[pyloop] PASSED                  [ 34%]\nr2e_tests/test_1.py::test_POST_FILES_STR_SIMPLE[pyloop] PASSED           [ 35%]\nr2e_tests/test_1.py::test_POST_FILES_LIST[pyloop] PASSED                 [ 35%]\nr2e_tests/test_1.py::test_POST_FILES_CT[pyloop] PASSED                   [ 36%]\nr2e_tests/test_1.py::test_POST_FILES_SINGLE[pyloop] PASSED               [ 36%]\nr2e_tests/test_1.py::test_POST_FILES_SINGLE_content_disposition[pyloop] PASSED [ 37%]\nr2e_tests/test_1.py::test_POST_FILES_SINGLE_BINARY[pyloop] PASSED        [ 37%]\nr2e_tests/test_1.py::test_POST_FILES_IO[pyloop] PASSED                   [ 38%]\nr2e_tests/test_1.py::test_POST_FILES_IO_WITH_PARAMS[pyloop] PASSED       [ 38%]\nr2e_tests/test_1.py::test_POST_FILES_WITH_DATA[pyloop] PASSED            [ 38%]\nr2e_tests/test_1.py::test_POST_STREAM_DATA[pyloop] PASSED                [ 39%]\nr2e_tests/test_1.py::test_json[pyloop] PASSED                            [ 39%]\nr2e_tests/test_1.py::test_json_custom[pyloop] PASSED                     [ 40%]\nr2e_tests/test_1.py::test_expect_continue[pyloop] PASSED                 [ 40%]\nr2e_tests/test_1.py::test_encoding_deflate[pyloop] PASSED                [ 41%]\nr2e_tests/test_1.py::test_encoding_deflate_nochunk[pyloop] PASSED        [ 41%]\nr2e_tests/test_1.py::test_encoding_gzip[pyloop] PASSED                   [ 42%]\nr2e_tests/test_1.py::test_encoding_gzip_write_by_chunks[pyloop] PASSED   [ 42%]\nr2e_tests/test_1.py::test_encoding_gzip_nochunk[pyloop] PASSED           [ 42%]\nr2e_tests/test_1.py::test_bad_payload_compression[pyloop] PASSED         [ 43%]\nr2e_tests/test_1.py::test_bad_payload_chunked_encoding[pyloop] PASSED    [ 43%]\nr2e_tests/test_1.py::test_no_payload_304_with_chunked_encoding[pyloop] PASSED [ 44%]\nr2e_tests/test_1.py::test_head_request_with_chunked_encoding[pyloop] PASSED [ 44%]\nr2e_tests/test_1.py::test_no_payload_200_with_chunked_encoding[pyloop] PASSED [ 45%]\nr2e_tests/test_1.py::test_bad_payload_content_length[pyloop] PASSED      [ 45%]\nr2e_tests/test_1.py::test_payload_content_length_by_chunks[pyloop] PASSED [ 46%]\nr2e_tests/test_1.py::test_chunked[pyloop] PASSED                         [ 46%]\nr2e_tests/test_1.py::test_shortcuts[pyloop] PASSED                       [ 46%]\nr2e_tests/test_1.py::test_cookies[pyloop] PASSED                         [ 47%]\nr2e_tests/test_1.py::test_cookies_per_request[pyloop] PASSED             [ 47%]\nr2e_tests/test_1.py::test_cookies_redirect[pyloop] PASSED                [ 48%]\nr2e_tests/test_1.py::test_cookies_on_empty_session_jar[pyloop] PASSED    [ 48%]\nr2e_tests/test_1.py::test_morsel_with_attributes[pyloop] PASSED          [ 49%]\nr2e_tests/test_1.py::test_set_cookies[pyloop] PASSED                     [ 49%]\nr2e_tests/test_1.py::test_set_cookies_expired[pyloop] PASSED             [ 50%]\nr2e_tests/test_1.py::test_set_cookies_max_age[pyloop] PASSED             [ 50%]\nr2e_tests/test_1.py::test_set_cookies_max_age_overflow[pyloop] PASSED    [ 50%]\nr2e_tests/test_1.py::test_request_conn_error PASSED                      [ 51%]\nr2e_tests/test_1.py::test_broken_connection[pyloop] XFAIL                [ 51%]\nr2e_tests/test_1.py::test_broken_connection_2[pyloop] PASSED             [ 52%]\nr2e_tests/test_1.py::test_custom_headers[pyloop] PASSED                  [ 52%]\nr2e_tests/test_1.py::test_redirect_to_absolute_url[pyloop] PASSED        [ 53%]\nr2e_tests/test_1.py::test_redirect_without_location_header[pyloop] PASSED [ 53%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http://:/-http://:/-InvalidUrlClientError] PASSED [ 53%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlClientError] PASSED [ 54%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http:/-http:///-InvalidUrlClientError] PASSED [ 54%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http:/example.com-http:///example.com-InvalidUrlClientError] PASSED [ 55%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[http:///example.com-http:///example.com-InvalidUrlClientError] PASSED [ 55%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[call:+380123456789-call:\\\\+380123456789-NonHttpUrlClientError] PASSED [ 56%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[skype:handle-skype:handle-NonHttpUrlClientError] PASSED [ 56%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[slack://instance/room-slack://instance/room-NonHttpUrlClientError] PASSED [ 57%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[steam:code-steam:code-NonHttpUrlClientError] PASSED [ 57%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[twitter://handle-twitter://handle-NonHttpUrlClientError] PASSED [ 57%]\nr2e_tests/test_1.py::test_invalid_and_non_http_url[bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlClientError] PASSED [ 58%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/-http:///-InvalidUrlRedirectClientError] PASSED [ 58%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 59%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 59%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError] PASSED [ 60%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError] PASSED [ 60%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError] PASSED [ 61%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError] PASSED [ 61%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError] PASSED [ 61%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError] PASSED [ 62%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError] PASSED [ 62%]\nr2e_tests/test_1.py::test_invalid_redirect_url[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError] PASSED [ 63%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/-http:///-InvalidUrlRedirectClientError] PASSED [ 63%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 64%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError] PASSED [ 64%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError] PASSED [ 65%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError] PASSED [ 65%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError] PASSED [ 65%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError] PASSED [ 66%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError] PASSED [ 66%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError] PASSED [ 67%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError] PASSED [ 67%]\nr2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError] PASSED [ 68%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-200-True] PASSED         [ 68%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-201-True] PASSED         [ 69%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-301-True] PASSED         [ 69%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-400-False] PASSED        [ 69%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-403-False] PASSED        [ 70%]\nr2e_tests/test_1.py::test_ok_from_status[pyloop-500-False] PASSED        [ 70%]\nr2e_tests/test_1.py::test_raise_for_status[pyloop] PASSED                [ 71%]\nr2e_tests/test_1.py::test_raise_for_status_per_request[pyloop] PASSED    [ 71%]\nr2e_tests/test_1.py::test_raise_for_status_disable_per_request[pyloop] PASSED [ 72%]\nr2e_tests/test_1.py::test_request_raise_for_status_default[pyloop] PASSED [ 72%]\nr2e_tests/test_1.py::test_request_raise_for_status_disabled[pyloop] PASSED [ 73%]\nr2e_tests/test_1.py::test_request_raise_for_status_enabled[pyloop] PASSED [ 73%]\nr2e_tests/test_1.py::test_session_raise_for_status_coro[pyloop] PASSED   [ 73%]\nr2e_tests/test_1.py::test_request_raise_for_status_coro[pyloop] PASSED   [ 74%]\nr2e_tests/test_1.py::test_invalid_idna PASSED                            [ 74%]\nr2e_tests/test_1.py::test_creds_in_auth_and_url PASSED                   [ 75%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts] PASSED [ 75%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-http -> https] PASSED [ 76%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-https -> http] PASSED [ 76%]\nr2e_tests/test_1.py::test_auth_persist_on_redirect_to_other_host_with_global_auth[pyloop] PASSED [ 76%]\nr2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url[pyloop] FAILED [ 77%]\nr2e_tests/test_1.py::test_async_with_session PASSED                      [ 77%]\nr2e_tests/test_1.py::test_session_close_awaitable PASSED                 [ 78%]\nr2e_tests/test_1.py::test_close_resp_on_error_async_with_session[pyloop] PASSED [ 78%]\nr2e_tests/test_1.py::test_release_resp_on_normal_exit_from_cm[pyloop] PASSED [ 79%]\nr2e_tests/test_1.py::test_non_close_detached_session_on_error_cm[pyloop] PASSED [ 79%]\nr2e_tests/test_1.py::test_close_detached_session_on_non_existing_addr PASSED [ 80%]\nr2e_tests/test_1.py::test_aiohttp_request_context_manager[pyloop] PASSED [ 80%]\nr2e_tests/test_1.py::test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop] PASSED [ 80%]\nr2e_tests/test_1.py::test_aiohttp_request_ctx_manager_not_found PASSED   [ 81%]\nr2e_tests/test_1.py::test_aiohttp_request_coroutine[pyloop] PASSED       [ 81%]\nr2e_tests/test_1.py::test_yield_from_in_session_request[pyloop] PASSED   [ 82%]\nr2e_tests/test_1.py::test_close_context_manager[pyloop] PASSED           [ 82%]\nr2e_tests/test_1.py::test_session_auth[pyloop] PASSED                    [ 83%]\nr2e_tests/test_1.py::test_session_auth_override[pyloop] PASSED           [ 83%]\nr2e_tests/test_1.py::test_session_auth_header_conflict[pyloop] PASSED    [ 84%]\nr2e_tests/test_1.py::test_session_headers[pyloop] PASSED                 [ 84%]\nr2e_tests/test_1.py::test_session_headers_merge[pyloop] PASSED           [ 84%]\nr2e_tests/test_1.py::test_multidict_headers[pyloop] PASSED               [ 85%]\nr2e_tests/test_1.py::test_request_conn_closed[pyloop] PASSED             [ 85%]\nr2e_tests/test_1.py::test_dont_close_explicit_connector[pyloop] PASSED   [ 86%]\nr2e_tests/test_1.py::test_server_close_keepalive_connection PASSED       [ 86%]\nr2e_tests/test_1.py::test_handle_keepalive_on_closed_connection PASSED   [ 87%]\nr2e_tests/test_1.py::test_error_in_performing_request[pyloop] PASSED     [ 87%]\nr2e_tests/test_1.py::test_await_after_cancelling[pyloop] PASSED          [ 88%]\nr2e_tests/test_1.py::test_async_payload_generator[pyloop] PASSED         [ 88%]\nr2e_tests/test_1.py::test_read_from_closed_response[pyloop] PASSED       [ 88%]\nr2e_tests/test_1.py::test_read_from_closed_response2[pyloop] PASSED      [ 89%]\nr2e_tests/test_1.py::test_read_from_closed_content[pyloop] PASSED        [ 89%]\nr2e_tests/test_1.py::test_read_timeout[pyloop] PASSED                    [ 90%]\nr2e_tests/test_1.py::test_socket_timeout[pyloop] PASSED                  [ 90%]\nr2e_tests/test_1.py::test_read_timeout_closes_connection[pyloop] PASSED  [ 91%]\nr2e_tests/test_1.py::test_read_timeout_on_prepared_response[pyloop] PASSED [ 91%]\nr2e_tests/test_1.py::test_timeout_with_full_buffer[pyloop] PASSED        [ 92%]\nr2e_tests/test_1.py::test_read_bufsize_session_default[pyloop] PASSED    [ 92%]\nr2e_tests/test_1.py::test_read_bufsize_explicit[pyloop] PASSED           [ 92%]\nr2e_tests/test_1.py::test_http_empty_data_text[pyloop] PASSED            [ 93%]\nr2e_tests/test_1.py::test_max_field_size_session_default[pyloop] PASSED  [ 93%]\nr2e_tests/test_1.py::test_max_field_size_session_default_fail[pyloop] PASSED [ 94%]\nr2e_tests/test_1.py::test_max_field_size_session_explicit[pyloop] PASSED [ 94%]\nr2e_tests/test_1.py::test_max_field_size_request_explicit[pyloop] PASSED [ 95%]\nr2e_tests/test_1.py::test_max_line_size_session_default[pyloop] PASSED   [ 95%]\nr2e_tests/test_1.py::test_max_line_size_session_default_fail[pyloop] PASSED [ 96%]\nr2e_tests/test_1.py::test_max_line_size_session_explicit[pyloop] PASSED  [ 96%]\nr2e_tests/test_1.py::test_max_line_size_request_explicit[pyloop] PASSED  [ 96%]\nr2e_tests/test_1.py::test_rejected_upload[pyloop] XFAIL (#7599)          [ 97%]\nr2e_tests/test_1.py::test_request_with_wrong_ssl_type[pyloop] PASSED     [ 97%]\nr2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-42-TypeError] PASSED [ 98%]\nr2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-InvalidUrl-InvalidURL] PASSED [ 98%]\nr2e_tests/test_1.py::test_raise_for_status_is_none[pyloop] PASSED        [ 99%]\nr2e_tests/test_1.py::test_header_too_large_error[pyloop] XFAIL (#839...) [ 99%]\nr2e_tests/test_1.py::test_exception_when_read_outside_of_session[pyloop] PASSED [100%]\n\n=================================== FAILURES ===================================\n_ test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url[pyloop] _\n\ncreate_server_for_url_and_handler = <function create_server_for_url_and_handler.<locals>.create at 0x75950b82a550>\n\n    async def test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url(\n        create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],\n    ) -> None:\n        url_from = URL(\"http://host1.com/path1\")\n        url_to = URL(\"http://host2.com/path2\")\n    \n        async def srv_from(request: web.Request) -> NoReturn:\n            assert request.host == url_from.host\n            assert request.headers[\"Authorization\"] == \"Basic dXNlcjpwYXNz\"\n            raise web.HTTPFound(url_to)\n    \n        async def srv_to(request: web.Request) -> web.Response:\n            assert request.host == url_to.host\n            assert \"Authorization\" not in request.headers, \"Header was not dropped\"\n            return web.Response()\n    \n        server_from = await create_server_for_url_and_handler(url_from, srv_from)\n        server_to = await create_server_for_url_and_handler(url_to, srv_to)\n    \n        assert (\n            url_from.host != url_to.host or server_from.scheme != server_to.scheme\n        ), \"Invalid test case, host or scheme must differ\"\n    \n        protocol_port_map = {\n            \"http\": 80,\n            \"https\": 443,\n        }\n        etc_hosts = {\n            (url_from.host, protocol_port_map[server_from.scheme]): server_from,\n            (url_to.host, protocol_port_map[server_to.scheme]): server_to,\n        }\n    \n        class FakeResolver(AbstractResolver):\n            async def resolve(\n                self,\n                host: str,\n                port: int = 0,\n                family: socket.AddressFamily = socket.AF_INET,\n            ) -> List[ResolveResult]:\n                server = etc_hosts[(host, port)]\n                assert server.port is not None\n    \n                return [\n                    {\n                        \"hostname\": host,\n                        \"host\": server.host,\n                        \"port\": server.port,\n                        \"family\": socket.AF_INET,\n                        \"proto\": 0,\n                        \"flags\": socket.AI_NUMERICHOST,\n                    }\n                ]\n    \n            async def close(self) -> None:\n                \"\"\"Dummy\"\"\"\n    \n        connector = aiohttp.TCPConnector(resolver=FakeResolver(), ssl=False)\n    \n        async with aiohttp.ClientSession(\n            connector=connector,\n            base_url=\"http://host1.com\",\n            auth=aiohttp.BasicAuth(\"user\", \"pass\"),\n        ) as client:\n            resp = await client.get(\"/path1\")\n>           assert resp.status == 200\nE           AssertionError: assert 500 == 200\nE            +  where 500 = <ClientResponse(http://host2.com/path2) [500 Internal Server Error]>\\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Thu, 02 Jan 2025 05:41:26 GMT', 'Server': 'Python/3.9 aiohttp/4.0.0a2.dev0', 'Connection': 'close')>\\n.status\n\nFakeResolver = <class 'r2e_tests.test_1.test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url.<locals>.FakeResolver'>\nclient     = <aiohttp.client.ClientSession object at 0x75950adc8e40>\nconnector  = <aiohttp.connector.TCPConnector object at 0x75950ac7b2e0>\ncreate_server_for_url_and_handler = <function create_server_for_url_and_handler.<locals>.create at 0x75950b82a550>\netc_hosts  = {('host1.com', 80): <aiohttp.test_utils.TestServer object at 0x75950ac7b130>, ('host2.com', 80): <aiohttp.test_utils.TestServer object at 0x75950ac7b160>}\nprotocol_port_map = {'http': 80, 'https': 443}\nresp       = <ClientResponse(http://host2.com/path2) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; ch...': '55', 'Date': 'Thu, 02 Jan 2025 05:41:26 GMT', 'Server': 'Python/3.9 aiohttp/4.0.0a2.dev0', 'Connection': 'close')>\n\nserver_from = <aiohttp.test_utils.TestServer object at 0x75950ac7b130>\nserver_to  = <aiohttp.test_utils.TestServer object at 0x75950ac7b160>\nsrv_from   = <function test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url.<locals>.srv_from at 0x75950b82a1f0>\nsrv_to     = <function test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url.<locals>.srv_to at 0x75950b82a820>\nurl_from   = URL('http://host1.com/path1')\nurl_to     = URL('http://host2.com/path2')\n\nr2e_tests/test_1.py:3093: AssertionError\n------------------------------ Captured log call -------------------------------\nERROR    aiohttp.server:web_protocol.py:447 Error handling request\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_protocol.py\", line 476, in _handle_request\n    resp = await request_handler(request)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_app.py\", line 388, in _handle\n    resp = await handler(request)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/r2e_tests/test_1.py\", line 3042, in srv_to\n    assert \"Authorization\" not in request.headers, \"Header was not dropped\"\nAssertionError: Header was not dropped\nassert 'Authorization' not in <CIMultiDictProxy('Host': 'host2.com', 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'User-Agent': 'Python/3.9 aiohttp/4.0.0a2.dev0', 'Authorization': 'Basic dXNlcjpwYXNz')>\n +  where <CIMultiDictProxy('Host': 'host2.com', 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'User-Agent': 'Python/3.9 aiohttp/4.0.0a2.dev0', 'Authorization': 'Basic dXNlcjpwYXNz')> = <Request GET /path2 >.headers\n================================== XFAILURES ===================================\n________________________ test_broken_connection[pyloop] ________________________\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b82a550>\n\n    @pytest.mark.xfail\n    async def test_broken_connection(aiohttp_client: AiohttpClient) -> None:\n        async def handler(request: web.Request) -> web.Response:\n            assert request.transport is not None\n            request.transport.close()\n            return web.Response(text=\"answer\" * 1000)\n    \n        app = web.Application()\n        app.router.add_get(\"/\", handler)\n        client = await aiohttp_client(app)\n    \n        with pytest.raises(aiohttp.ClientResponseError):\n>           await client.get(\"/\")\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b82a550>\napp        = <Application 0x75950ad56460>\nclient     = <aiohttp.test_utils.TestClient object at 0x75950ad8f6a0>\nhandler    = <function test_broken_connection.<locals>.handler at 0x75950b656f70>\n\nr2e_tests/test_1.py:2487: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/test_utils.py:323: in _request\n    resp = await self._session.request(method, self.make_url(path), **kwargs)\n        kwargs     = {}\n        method     = 'GET'\n        path       = '/'\n        self       = <aiohttp.test_utils.TestClient object at 0x75950ad8f6a0>\naiohttp/client.py:631: in _request\n    await resp.start(conn)\n        all_cookies = <SimpleCookie: >\n        allow_redirects = True\n        auth       = None\n        auth_from_url = None\n        auto_decompress = True\n        chunked    = None\n        compress   = None\n        conn       = Connection<ConnectionKey(host='127.0.0.1', port=42901, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        cookies    = None\n        data       = None\n        expect100  = False\n        handle     = None\n        headers    = <CIMultiDict()>\n        history    = []\n        json       = None\n        max_field_size = 8190\n        max_line_size = 8190\n        max_redirects = 10\n        method     = 'GET'\n        params     = {}\n        proxy      = None\n        proxy_auth = None\n        proxy_headers = <CIMultiDict()>\n        raise_for_status = None\n        read_bufsize = 65536\n        read_until_eof = True\n        real_timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        redirects  = 0\n        req        = <aiohttp.client_reqrep.ClientRequest object at 0x75950ad55850>\n        resp       = <ClientResponse(http://127.0.0.1:42901/) [None None]>\nNone\n\n        retry_persistent_connection = False\n        self       = <aiohttp.client.ClientSession object at 0x75950adc8740>\n        server_hostname = None\n        skip_auto_headers = None\n        skip_headers = set()\n        ssl        = True\n        str_or_url = URL('http://127.0.0.1:42901/')\n        timeout    = <_SENTINEL.sentinel: 1>\n        timer      = <aiohttp.helpers.TimerContext object at 0x75950ad55310>\n        tm         = <aiohttp.helpers.TimeoutHandle object at 0x75950ad55280>\n        trace_request_ctx = None\n        traces     = []\n        url        = URL('http://127.0.0.1:42901/')\n        version    = HttpVersion(major=1, minor=1)\naiohttp/client_reqrep.py:931: in start\n    message, payload = await protocol.read()  # type: ignore[union-attr]\n        connection = Connection<ConnectionKey(host='127.0.0.1', port=42901, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        protocol   = <aiohttp.client_proto.ResponseHandler object at 0x75950b661d60>\n        self       = <ClientResponse(http://127.0.0.1:42901/) [None None]>\nNone\n\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <aiohttp.client_proto.ResponseHandler object at 0x75950b661d60>\n\n    async def read(self) -> _SizedT:\n        if not self._buffer and not self._eof:\n            assert not self._waiter\n            self._waiter = self._loop.create_future()\n            try:\n>               await self._waiter\nE               aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected\n\nself       = <aiohttp.client_proto.ResponseHandler object at 0x75950b661d60>\n\naiohttp/streams.py:631: ServerDisconnectedError\n_________________________ test_rejected_upload[pyloop] _________________________\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b656dc0>\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-619/test_rejected_upload_pyloop_0')\n\n    @pytest.mark.xfail(raises=asyncio.TimeoutError, reason=\"#7599\")\n    async def test_rejected_upload(\n        aiohttp_client: AiohttpClient, tmp_path: pathlib.Path\n    ) -> None:\n        async def ok_handler(request: web.Request) -> web.Response:\n            return web.Response()\n    \n        async def not_ok_handler(request: web.Request) -> NoReturn:\n            raise web.HTTPBadRequest()\n    \n        app = web.Application()\n        app.router.add_get(\"/ok\", ok_handler)\n        app.router.add_post(\"/not_ok\", not_ok_handler)\n        client = await aiohttp_client(app)\n    \n        file_size_bytes = 1024 * 1024\n        file_path = tmp_path / \"uploaded.txt\"\n        file_path.write_text(\"0\" * file_size_bytes, encoding=\"utf8\")\n    \n        with open(file_path, \"rb\") as file:\n            data = {\"file\": file}\n            async with await client.post(\"/not_ok\", data=data) as resp_not_ok:\n                assert 400 == resp_not_ok.status\n    \n>       async with await client.get(\n            \"/ok\", timeout=aiohttp.ClientTimeout(total=0.01)\n        ) as resp_ok:\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b656dc0>\napp        = <Application 0x75950ace6670>\nclient     = <aiohttp.test_utils.TestClient object at 0x75950ad5e3a0>\ndata       = {'file': <_io.BufferedReader name='/tmp/pytest-of-gcpuser/pytest-619/test_rejected_upload_pyloop_0/uploaded.txt'>}\nfile       = <_io.BufferedReader name='/tmp/pytest-of-gcpuser/pytest-619/test_rejected_upload_pyloop_0/uploaded.txt'>\nfile_path  = PosixPath('/tmp/pytest-of-gcpuser/pytest-619/test_rejected_upload_pyloop_0/uploaded.txt')\nfile_size_bytes = 1048576\nnot_ok_handler = <function test_rejected_upload.<locals>.not_ok_handler at 0x75950acc95e0>\nok_handler = <function test_rejected_upload.<locals>.ok_handler at 0x75950acc9550>\nresp_not_ok = <ClientResponse(http://127.0.0.1:41457/not_ok) [400 Bad Request]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '16', 'Date': 'Thu, 02 Jan 2025 05:41:28 GMT', 'Server': 'Python/3.9 aiohttp/4.0.0a2.dev0')>\n\ntmp_path   = PosixPath('/tmp/pytest-of-gcpuser/pytest-619/test_rejected_upload_pyloop_0')\n\nr2e_tests/test_1.py:3909: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/test_utils.py:323: in _request\n    resp = await self._session.request(method, self.make_url(path), **kwargs)\n        kwargs     = {'timeout': ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)}\n        method     = 'GET'\n        path       = '/ok'\n        self       = <aiohttp.test_utils.TestClient object at 0x75950ad5e3a0>\naiohttp/client.py:631: in _request\n    await resp.start(conn)\n        all_cookies = <SimpleCookie: >\n        allow_redirects = True\n        auth       = None\n        auth_from_url = None\n        auto_decompress = True\n        chunked    = None\n        compress   = None\n        conn       = Connection<ConnectionKey(host='127.0.0.1', port=41457, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        cookies    = None\n        data       = None\n        expect100  = False\n        handle     = None\n        headers    = <CIMultiDict()>\n        history    = []\n        json       = None\n        max_field_size = 8190\n        max_line_size = 8190\n        max_redirects = 10\n        method     = 'GET'\n        params     = {}\n        proxy      = None\n        proxy_auth = None\n        proxy_headers = <CIMultiDict()>\n        raise_for_status = None\n        read_bufsize = 65536\n        read_until_eof = True\n        real_timeout = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        redirects  = 0\n        req        = <aiohttp.client_reqrep.ClientRequest object at 0x759509597340>\n        resp       = <ClientResponse(http://127.0.0.1:41457/ok) [None None]>\nNone\n\n        retry_persistent_connection = True\n        self       = <aiohttp.client.ClientSession object at 0x75950ad6b660>\n        server_hostname = None\n        skip_auto_headers = None\n        skip_headers = set()\n        ssl        = True\n        str_or_url = URL('http://127.0.0.1:41457/ok')\n        timeout    = ClientTimeout(total=0.01, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        timer      = <aiohttp.helpers.TimerContext object at 0x759509597280>\n        tm         = <aiohttp.helpers.TimeoutHandle object at 0x759509597ee0>\n        trace_request_ctx = None\n        traces     = []\n        url        = URL('http://127.0.0.1:41457/ok')\n        version    = HttpVersion(major=1, minor=1)\naiohttp/client_reqrep.py:946: in start\n    self._continue = None\n        connection = Connection<ConnectionKey(host='127.0.0.1', port=41457, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        protocol   = <aiohttp.client_proto.ResponseHandler object at 0x75950b6613a0>\n        self       = <ClientResponse(http://127.0.0.1:41457/ok) [None None]>\nNone\n\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <aiohttp.helpers.TimerContext object at 0x759509597280>\nexc_type = <class 'asyncio.exceptions.CancelledError'>\nexc_val = CancelledError(), exc_tb = <traceback object at 0x75950acd3bc0>\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> Optional[bool]:\n        if self._tasks:\n            self._tasks.pop()  # type: ignore[unused-awaitable]\n    \n        if exc_type is asyncio.CancelledError and self._cancelled:\n>           raise asyncio.TimeoutError from None\nE           asyncio.exceptions.TimeoutError\n\nexc_tb     = <traceback object at 0x75950acd3bc0>\nexc_type   = <class 'asyncio.exceptions.CancelledError'>\nexc_val    = CancelledError()\nself       = <aiohttp.helpers.TimerContext object at 0x759509597280>\n\naiohttp/helpers.py:724: TimeoutError\n_____________________ test_header_too_large_error[pyloop] ______________________\n\nself = <aiohttp.client_proto.ResponseHandler object at 0x7595099353a0>\ndata = b'HTTP/1.1 200 OK\\r\\nVeryLargeHeader: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxx\\r\\nContent-Length: 0\\r\\nDate: Thu, 02 Jan 2025 05:41:28 GMT\\r\\nServer: Python/3.9 aiohttp/4.0.0a2.dev0\\r\\n\\r\\n'\n\n    def data_received(self, data: bytes) -> None:\n        self._reschedule_timeout()\n    \n        if not data:\n            return\n    \n        # custom payload parser\n        if self._payload_parser is not None:\n            eof, tail = self._payload_parser.feed_data(data)\n            if eof:\n                self._payload = None\n                self._payload_parser = None\n    \n                if tail:\n                    self.data_received(tail)\n            return\n        else:\n            if self._upgraded or self._parser is None:\n                # i.e. websocket connection, websocket parser is not set yet\n                self._tail += data\n            else:\n                # parse http messages\n                try:\n>                   messages, upgraded, tail = self._parser.feed_data(data)\n\ndata       = b'HTTP/1.1 200 OK\\r\\nVeryLargeHeader: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxx\\r\\nContent-Length: 0\\r\\nDate: Thu, 02 Jan 2025 05:41:28 GMT\\r\\nServer: Python/3.9 aiohttp/4.0.0a2.dev0\\r\\n\\r\\n'\nself       = <aiohttp.client_proto.ResponseHandler object at 0x7595099353a0>\n\naiohttp/client_proto.py:277: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/_http_parser.pyx:563: in aiohttp._http_parser.HttpParser.feed_data\n    raise ex\n        ALLOWED_UPGRADES = frozenset({'websocket'})\n        BadHttpMessage = <class 'aiohttp.http_exceptions.BadHttpMessage'>\n        BadStatusLine = <class 'aiohttp.http_exceptions.BadStatusLine'>\n        ContentLengthError = <class 'aiohttp.http_exceptions.ContentLengthError'>\n        DEBUG      = False\n        HttpRequestParser = <class 'aiohttp._http_parser.HttpRequestParser'>\n        HttpResponseParser = <class 'aiohttp._http_parser.HttpResponseParser'>\n        InvalidHeader = <class 'aiohttp.http_exceptions.InvalidHeader'>\n        InvalidURLError = <class 'aiohttp.http_exceptions.InvalidURLError'>\n        LineTooLong = <class 'aiohttp.http_exceptions.LineTooLong'>\n        PayloadEncodingError = <class 'aiohttp.http_exceptions.PayloadEncodingError'>\n        RawRequestMessage = <class 'aiohttp._http_parser.RawRequestMessage'>\n        RawResponseMessage = <class 'aiohttp._http_parser.RawResponseMessage'>\n        TransferEncodingError = <class 'aiohttp.http_exceptions.TransferEncodingError'>\n        _CIMultiDict = <class 'multidict._multidict.CIMultiDict'>\n        _CIMultiDictProxy = <class 'multidict._multidict.CIMultiDictProxy'>\n        _DeflateBuffer = <class 'aiohttp.http_parser.DeflateBuffer'>\n        _EMPTY_PAYLOAD = <EmptyStreamReader>\n        _HttpVersion = <class 'aiohttp.http_writer.HttpVersion'>\n        _HttpVersion10 = HttpVersion(major=1, minor=0)\n        _HttpVersion11 = HttpVersion(major=1, minor=1)\n        _StreamReader = <class 'aiohttp.streams.StreamReader'>\n        _URL       = <class 'yarl.URL'>\n        __all__    = ('HttpRequestParser', 'HttpResponseParser', 'RawRequestMessage', 'RawResponseMessage')\n        __builtins__ = <builtins>\n        __doc__    = None\n        __file__   = '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so'\n        __loader__ = <_frozen_importlib_external.ExtensionFileLoader object at 0x75950d0b7790>\n        __name__   = 'aiohttp._http_parser'\n        __package__ = 'aiohttp'\n        __pyx_unpickle_RawRequestMessage = <cyfunction __pyx_unpickle_RawRequestMessage at 0x75950d179a00>\n        __pyx_unpickle_RawResponseMessage = <cyfunction __pyx_unpickle_RawResponseMessage at 0x75950d179c70>\n        __reduce_cython__ = <cyfunction HttpResponseParser.__reduce_cython__ at 0x75950d179ad0>\n        __setstate_cython__ = <cyfunction HttpResponseParser.__setstate_cython__ at 0x75950d179ba0>\n        __spec__   = ModuleSpec(name='aiohttp._http_parser', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x75950d0b779...val_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so')\n        __test__   = {}\n        hdrs       = <module 'aiohttp.hdrs' from '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/hdrs.py'>\n        i          = 45\n        set_exception = <function set_exception at 0x75950d1baf70>\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n>   raise LineTooLong(\nE   aiohttp.http_exceptions.LineTooLong: 400, message:\nE     Got more than 8190 bytes (10000) when reading Header value is too long.\n\nALLOWED_UPGRADES = frozenset({'websocket'})\nBadHttpMessage = <class 'aiohttp.http_exceptions.BadHttpMessage'>\nBadStatusLine = <class 'aiohttp.http_exceptions.BadStatusLine'>\nContentLengthError = <class 'aiohttp.http_exceptions.ContentLengthError'>\nDEBUG      = False\nHttpRequestParser = <class 'aiohttp._http_parser.HttpRequestParser'>\nHttpResponseParser = <class 'aiohttp._http_parser.HttpResponseParser'>\nInvalidHeader = <class 'aiohttp.http_exceptions.InvalidHeader'>\nInvalidURLError = <class 'aiohttp.http_exceptions.InvalidURLError'>\nLineTooLong = <class 'aiohttp.http_exceptions.LineTooLong'>\nPayloadEncodingError = <class 'aiohttp.http_exceptions.PayloadEncodingError'>\nRawRequestMessage = <class 'aiohttp._http_parser.RawRequestMessage'>\nRawResponseMessage = <class 'aiohttp._http_parser.RawResponseMessage'>\nTransferEncodingError = <class 'aiohttp.http_exceptions.TransferEncodingError'>\n_CIMultiDict = <class 'multidict._multidict.CIMultiDict'>\n_CIMultiDictProxy = <class 'multidict._multidict.CIMultiDictProxy'>\n_DeflateBuffer = <class 'aiohttp.http_parser.DeflateBuffer'>\n_EMPTY_PAYLOAD = <EmptyStreamReader>\n_HttpVersion = <class 'aiohttp.http_writer.HttpVersion'>\n_HttpVersion10 = HttpVersion(major=1, minor=0)\n_HttpVersion11 = HttpVersion(major=1, minor=1)\n_StreamReader = <class 'aiohttp.streams.StreamReader'>\n_URL       = <class 'yarl.URL'>\n__all__    = ('HttpRequestParser', 'HttpResponseParser', 'RawRequestMessage', 'RawResponseMessage')\n__builtins__ = <builtins>\n__doc__    = None\n__file__   = '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so'\n__loader__ = <_frozen_importlib_external.ExtensionFileLoader object at 0x75950d0b7790>\n__name__   = 'aiohttp._http_parser'\n__package__ = 'aiohttp'\n__pyx_unpickle_RawRequestMessage = <cyfunction __pyx_unpickle_RawRequestMessage at 0x75950d179a00>\n__pyx_unpickle_RawResponseMessage = <cyfunction __pyx_unpickle_RawResponseMessage at 0x75950d179c70>\n__reduce_cython__ = <cyfunction HttpResponseParser.__reduce_cython__ at 0x75950d179ad0>\n__setstate_cython__ = <cyfunction HttpResponseParser.__setstate_cython__ at 0x75950d179ba0>\n__spec__   = ModuleSpec(name='aiohttp._http_parser', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x75950d0b779...val_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/_http_parser.cpython-39-x86_64-linux-gnu.so')\n__test__   = {}\nhdrs       = <module 'aiohttp.hdrs' from '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/hdrs.py'>\ni          = 45\nset_exception = <function set_exception at 0x75950d1baf70>\n\naiohttp/_http_parser.pyx:738: LineTooLong\n\nThe above exception was the direct cause of the following exception:\n\nself = <ClientResponse(http://127.0.0.1:38659/) [None None]>\nNone\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=38659, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n\n    async def start(self, connection: \"Connection\") -> \"ClientResponse\":\n        \"\"\"Start response processing.\"\"\"\n        self._closed = False\n        self._protocol = connection.protocol\n        self._connection = connection\n    \n        with self._timer:\n            while True:\n                # read response\n                try:\n                    protocol = self._protocol\n>                   message, payload = await protocol.read()  # type: ignore[union-attr]\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=38659, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\nprotocol   = <aiohttp.client_proto.ResponseHandler object at 0x7595099353a0>\nself       = <ClientResponse(http://127.0.0.1:38659/) [None None]>\nNone\n\n\naiohttp/client_reqrep.py:931: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <aiohttp.client_proto.ResponseHandler object at 0x7595099353a0>\n\n    async def read(self) -> _SizedT:\n        if not self._buffer and not self._eof:\n            assert not self._waiter\n            self._waiter = self._loop.create_future()\n            try:\n>               await self._waiter\nE               aiohttp.http_exceptions.HttpProcessingError: 0, message:\n\nself       = <aiohttp.client_proto.ResponseHandler object at 0x7595099353a0>\n\naiohttp/streams.py:631: HttpProcessingError\n\nThe above exception was the direct cause of the following exception:\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b656ee0>\n\n    @pytest.mark.xfail(\n        reason=\"#8395 Error message regression for large headers in 3.9.4\",\n        raises=AssertionError,\n    )\n    async def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n        \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n    \n        async def handler(_: web.Request) -> web.Response:\n            return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n    \n        app = web.Application()\n        app.add_routes([web.get(\"/\", handler)])\n        client = await aiohttp_client(app)\n    \n        with pytest.raises(\n            aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n        ) as exc_info:\n>           await client.get(\"/\")\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b656ee0>\napp        = <Application 0x75950ace6b40>\nclient     = <aiohttp.test_utils.TestClient object at 0x759509597820>\nexc_info   = <ExceptionInfo ClientResponseError(RequestInfo(url=URL('http://127.0.0.1:38659/'), method='GET', headers=<CIMultiDictP...deflate, br', 'User-Agent': 'Python/3.9 aiohttp/4.0.0a2.dev0')>, real_url=URL('http://127.0.0.1:38659/')), ()) tblen=4>\nhandler    = <function test_header_too_large_error.<locals>.handler at 0x75950ad34670>\n\nr2e_tests/test_1.py:3965: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \naiohttp/test_utils.py:323: in _request\n    resp = await self._session.request(method, self.make_url(path), **kwargs)\n        kwargs     = {}\n        method     = 'GET'\n        path       = '/'\n        self       = <aiohttp.test_utils.TestClient object at 0x759509597820>\naiohttp/client.py:631: in _request\n    await resp.start(conn)\n        all_cookies = <SimpleCookie: >\n        allow_redirects = True\n        auth       = None\n        auth_from_url = None\n        auto_decompress = True\n        chunked    = None\n        compress   = None\n        conn       = Connection<ConnectionKey(host='127.0.0.1', port=38659, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n        cookies    = None\n        data       = None\n        expect100  = False\n        handle     = None\n        headers    = <CIMultiDict()>\n        history    = []\n        json       = None\n        max_field_size = 8190\n        max_line_size = 8190\n        max_redirects = 10\n        method     = 'GET'\n        params     = {}\n        proxy      = None\n        proxy_auth = None\n        proxy_headers = <CIMultiDict()>\n        raise_for_status = None\n        read_bufsize = 65536\n        read_until_eof = True\n        real_timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=None, ceil_threshold=5)\n        redirects  = 0\n        req        = <aiohttp.client_reqrep.ClientRequest object at 0x75950941f820>\n        resp       = <ClientResponse(http://127.0.0.1:38659/) [None None]>\nNone\n\n        retry_persistent_connection = True\n        self       = <aiohttp.client.ClientSession object at 0x75950ad6be40>\n        server_hostname = None\n        skip_auto_headers = None\n        skip_headers = set()\n        ssl        = True\n        str_or_url = URL('http://127.0.0.1:38659/')\n        timeout    = <_SENTINEL.sentinel: 1>\n        timer      = <aiohttp.helpers.TimerContext object at 0x75950941fbe0>\n        tm         = <aiohttp.helpers.TimeoutHandle object at 0x75950941fc40>\n        trace_request_ctx = None\n        traces     = []\n        url        = URL('http://127.0.0.1:38659/')\n        version    = HttpVersion(major=1, minor=1)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <ClientResponse(http://127.0.0.1:38659/) [None None]>\nNone\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=38659, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\n\n    async def start(self, connection: \"Connection\") -> \"ClientResponse\":\n        \"\"\"Start response processing.\"\"\"\n        self._closed = False\n        self._protocol = connection.protocol\n        self._connection = connection\n    \n        with self._timer:\n            while True:\n                # read response\n                try:\n                    protocol = self._protocol\n                    message, payload = await protocol.read()  # type: ignore[union-attr]\n                except http.HttpProcessingError as exc:\n>                   raise ClientResponseError(\n                        self.request_info,\n                        self.history,\n                        status=exc.code,\n                        message=exc.message,\n                        headers=exc.headers,\n                    ) from exc\nE                   aiohttp.client_exceptions.ClientResponseError: 0, message='', url='http://127.0.0.1:38659/'\n\nconnection = Connection<ConnectionKey(host='127.0.0.1', port=38659, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None)>\nprotocol   = <aiohttp.client_proto.ResponseHandler object at 0x7595099353a0>\nself       = <ClientResponse(http://127.0.0.1:38659/) [None None]>\nNone\n\n\naiohttp/client_reqrep.py:933: ClientResponseError\n\nDuring handling of the above exception, another exception occurred:\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b656ee0>\n\n    @pytest.mark.xfail(\n        reason=\"#8395 Error message regression for large headers in 3.9.4\",\n        raises=AssertionError,\n    )\n    async def test_header_too_large_error(aiohttp_client: AiohttpClient) -> None:\n        \"\"\"By default when not specifying `max_field_size` requests should fail with a 400 status code.\"\"\"\n    \n        async def handler(_: web.Request) -> web.Response:\n            return web.Response(headers={\"VeryLargeHeader\": \"x\" * 10000})\n    \n        app = web.Application()\n        app.add_routes([web.get(\"/\", handler)])\n        client = await aiohttp_client(app)\n    \n        with pytest.raises(\n            aiohttp.ClientResponseError, match=\"Got more than 8190 bytes*\"\n        ) as exc_info:\n>           await client.get(\"/\")\nE           AssertionError: Regex pattern did not match.\nE            Regex: 'Got more than 8190 bytes*'\nE            Input: \"0, message='', url='http://127.0.0.1:38659/'\"\n\naiohttp_client = <function aiohttp_client.<locals>.go at 0x75950b656ee0>\napp        = <Application 0x75950ace6b40>\nclient     = <aiohttp.test_utils.TestClient object at 0x759509597820>\nexc_info   = <ExceptionInfo ClientResponseError(RequestInfo(url=URL('http://127.0.0.1:38659/'), method='GET', headers=<CIMultiDictP...deflate, br', 'User-Agent': 'Python/3.9 aiohttp/4.0.0a2.dev0')>, real_url=URL('http://127.0.0.1:38659/')), ()) tblen=4>\nhandler    = <function test_header_too_large_error.<locals>.handler at 0x75950ad34670>\n\nr2e_tests/test_1.py:3965: AssertionError\n==================================== PASSES ====================================\n______________________ test_keepalive_timeout_sync_sleep _______________________\n------------------------------ Captured log call -------------------------------\nERROR    asyncio:base_events.py:1753 Task exception was never retrieved\nfuture: <Task finished name='Task-116' coro=<RequestHandler.start() done, defined at /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_protocol.py:501> exception=AssertionError()>\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_protocol.py\", line 544, in start\n    request = self._request_factory(message, payload, self, writer, handler)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_runner.py\", line 425, in _make_request\n    return _cls(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_request.py\", line 840, in __init__\n    super().__init__(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_f569894caa7cfbc2ec03fb5eed6021b9899dc4b4/aiohttp/web_request.py\", line 198, in __init__\n    assert transport is not None\nAssertionError\n---------------------------- Captured log teardown -----------------------------\nERROR    asyncio:base_events.py:1753 Unclosed client session\nclient_session: <aiohttp.client.ClientSession object at 0x75950ad5a120>\n____________________ test_aiohttp_request_coroutine[pyloop] ____________________\n------------------------------ Captured log call -------------------------------\nERROR    asyncio:base_events.py:1753 Unclosed client session\nclient_session: <aiohttp.client.ClientSession object at 0x75950ad6b4a0>\n\n---------- coverage: platform linux, python 3.9.21-final-0 -----------\nName                                     Stmts   Miss Branch BrPart  Cover\n--------------------------------------------------------------------------\naiohttp/__init__.py                         26      8      2      1    68%\naiohttp/abc.py                              97      2      0      0    98%\naiohttp/base_protocol.py                    67     28     22      5    49%\naiohttp/client.py                          520    105    186     16    77%\naiohttp/client_exceptions.py               139     21     14      4    84%\naiohttp/client_proto.py                    168     30     58     11    78%\naiohttp/client_reqrep.py                   659    114    280     56    78%\naiohttp/client_ws.py                       264    211     82      1    16%\naiohttp/compression_utils.py                70     15     14      1    71%\naiohttp/connector.py                       720    250    301     52    59%\naiohttp/cookiejar.py                       253     60    120     24    73%\naiohttp/formdata.py                         86      7     38      5    90%\naiohttp/hdrs.py                             90      0      0      0   100%\naiohttp/helpers.py                         550    188    200     35    61%\naiohttp/http.py                              8      0      0      0   100%\naiohttp/http_exceptions.py                  48      8      2      1    82%\naiohttp/http_parser.py                     492    339    206     11    24%\naiohttp/http_websocket.py                  382    285    154      0    18%\naiohttp/http_writer.py                     118     12     50      5    86%\naiohttp/locks.py                            24     10      4      0    50%\naiohttp/log.py                               7      0      0      0   100%\naiohttp/multipart.py                       625    293    268     49    46%\naiohttp/payload.py                         237     22     58     12    86%\naiohttp/pytest_plugin.py                   160     44     42      7    70%\naiohttp/resolver.py                         61     24     18      3    53%\naiohttp/streams.py                         395    113    142     18    67%\naiohttp/tcp_helpers.py                      19      2      6      3    80%\naiohttp/test_utils.py                      304    103     54     13    61%\naiohttp/tracing.py                         193     17     32      0    92%\naiohttp/typedefs.py                         23      0      0      0   100%\naiohttp/web.py                             124     86     52      0    23%\naiohttp/web_app.py                         233     80     50     11    59%\naiohttp/web_exceptions.py                  214     28     26      7    83%\naiohttp/web_fileresponse.py                160    126     52      0    18%\naiohttp/web_log.py                         102     37     20      1    59%\naiohttp/web_middlewares.py                  54     38     20      0    22%\naiohttp/web_protocol.py                    363     76    155     51    72%\naiohttp/web_request.py                     440    170    136     23    55%\naiohttp/web_response.py                    435    101    192     38    71%\naiohttp/web_routedef.py                    100     37     10      1    62%\naiohttp/web_runner.py                      222     60     40     13    68%\naiohttp/web_server.py                       49      6     14      2    84%\naiohttp/web_urldispatcher.py               721    317    153     21    52%\naiohttp/web_ws.py                          383    311    132      1    15%\naiohttp/worker.py                          123    123     30      0     0%\ntests/conftest.py                          130    130     16      0     0%\ntests/test_base_protocol.py                198    198      2      0     0%\ntests/test_circular_imports.py              29     29     13      0     0%\ntests/test_classbasedview.py                39     39      0      0     0%\ntests/test_client_connection.py             93     93      2      0     0%\ntests/test_client_exceptions.py            182    182     14      0     0%\ntests/test_client_fingerprint.py            24     24      0      0     0%\ntests/test_client_functional.py           2460   2460     72      0     0%\ntests/test_client_proto.py                 103    103      0      0     0%\ntests/test_client_request.py               780    780     18      0     0%\ntests/test_client_response.py              488    488      4      0     0%\ntests/test_client_session.py               533    533     29      0     0%\ntests/test_client_ws.py                    487    487      2      0     0%\ntests/test_client_ws_functional.py         782    782     22      0     0%\ntests/test_connector.py                   1673   1673     78      0     0%\ntests/test_cookiejar.py                    358    358     20      0     0%\ntests/test_flowcontrol_streams.py           98     98      0      0     0%\ntests/test_formdata.py                      81     81      4      0     0%\ntests/test_helpers.py                      569    569     22      0     0%\ntests/test_http_exceptions.py              110    110     10      0     0%\ntests/test_http_parser.py                 1087   1087     44      0     0%\ntests/test_http_writer.py                  178    178     10      0     0%\ntests/test_imports.py                       34     34      6      0     0%\ntests/test_locks.py                         40     40      0      0     0%\ntests/test_loop.py                          36     36      0      0     0%\ntests/test_multipart.py                    869    869     34      0     0%\ntests/test_multipart_helpers.py            446    446      0      0     0%\ntests/test_payload.py                       80     80      0      0     0%\ntests/test_proxy.py                        335    335      0      0     0%\ntests/test_proxy_functional.py             465    465     20      0     0%\ntests/test_pytest_plugin.py                 47     47      0      0     0%\ntests/test_resolver.py                     177    177     18      0     0%\ntests/test_route_def.py                    191    191      0      0     0%\ntests/test_run_app.py                      576    576     30      0     0%\ntests/test_streams.py                     1060   1060     38      0     0%\ntests/test_tcp_helpers.py                   52     52      2      0     0%\ntests/test_test_utils.py                   237    237      6      0     0%\ntests/test_tracing.py                       49     49      0      0     0%\ntests/test_urldispatch.py                  854    854     24      0     0%\ntests/test_web_app.py                      383    383      6      0     0%\ntests/test_web_cli.py                       76     76      0      0     0%\ntests/test_web_exceptions.py               274    274     30      0     0%\ntests/test_web_functional.py              1503   1503     30      0     0%\ntests/test_web_log.py                      143    143      2      0     0%\ntests/test_web_middleware.py               230    230      2      0     0%\ntests/test_web_request.py                  533    533      8      0     0%\ntests/test_web_request_handler.py           42     42      0      0     0%\ntests/test_web_response.py                 834    834      6      0     0%\ntests/test_web_runner.py                   180    180      4      0     0%\ntests/test_web_sendfile.py                  85     85      0      0     0%\ntests/test_web_sendfile_functional.py      656    656     18      0     0%\ntests/test_web_server.py                   177    177      0      0     0%\ntests/test_web_urldispatcher.py            504    504     24      0     0%\ntests/test_web_websocket.py                383    383      8      0     0%\ntests/test_web_websocket_functional.py     799    799     32      0     0%\ntests/test_websocket_handshake.py          153    153     12      0     0%\ntests/test_websocket_parser.py             290    290     12      0     0%\ntests/test_websocket_writer.py              96     96      6      0     0%\ntests/test_worker.py                       190    190      2      0     0%\n--------------------------------------------------------------------------\nTOTAL                                    34089  27468   4197    502    21%\n\n============================= slowest 10 durations =============================\n2.01s call     r2e_tests/test_1.py::test_read_timeout_between_chunks[pyloop]\n2.01s call     r2e_tests/test_1.py::test_set_cookies_max_age[pyloop]\n1.00s call     r2e_tests/test_1.py::test_readline_error_on_conn_close[pyloop]\n1.00s call     r2e_tests/test_1.py::test_timeout_on_reading_data[pyloop]\n0.51s call     r2e_tests/test_1.py::test_timeout_with_full_buffer[pyloop]\n0.50s call     r2e_tests/test_1.py::test_no_error_on_conn_close_if_eof[pyloop]\n0.50s call     r2e_tests/test_1.py::test_read_timeout_on_write[pyloop]\n0.21s call     r2e_tests/test_1.py::test_read_timeout_closes_connection[pyloop]\n0.20s call     r2e_tests/test_1.py::test_read_timeout_on_reading_chunks[pyloop]\n0.10s call     r2e_tests/test_1.py::test_read_timeout_on_prepared_response[pyloop]\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::test_keepalive_two_requests_success[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_after_head_requests_success[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-101]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-204]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status[pyloop-304]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-101]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-204]\nPASSED r2e_tests/test_1.py::test_keepalive_after_empty_body_status_stream_response[pyloop-304]\nPASSED r2e_tests/test_1.py::test_keepalive_response_released[pyloop]\nPASSED r2e_tests/test_1.py::test_upgrade_connection_not_released_after_read[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_server_force_close_connection[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_timeout_async_sleep\nPASSED r2e_tests/test_1.py::test_keepalive_timeout_sync_sleep\nPASSED r2e_tests/test_1.py::test_release_early[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_304[pyloop]\nPASSED r2e_tests/test_1.py::test_stream_request_on_server_eof[pyloop]\nPASSED r2e_tests/test_1.py::test_stream_request_on_server_eof_nested[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_304_WITH_BODY[pyloop]\nPASSED r2e_tests/test_1.py::test_auto_header_user_agent[pyloop]\nPASSED r2e_tests/test_1.py::test_skip_auto_headers_user_agent[pyloop]\nPASSED r2e_tests/test_1.py::test_skip_default_auto_headers_user_agent[pyloop]\nPASSED r2e_tests/test_1.py::test_skip_auto_headers_content_type[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_bytesio[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_with_bytesio_file[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_stringio[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_textio_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_zipfile_filelike[pyloop]\nPASSED r2e_tests/test_1.py::test_post_data_tarfile_filelike[pyloop]\nPASSED r2e_tests/test_1.py::test_ssl_client[pyloop]\nPASSED r2e_tests/test_1.py::test_tcp_connector_fingerprint_ok[pyloop]\nPASSED r2e_tests/test_1.py::test_tcp_connector_fingerprint_fail[pyloop]\nPASSED r2e_tests/test_1.py::test_format_task_get[pyloop]\nPASSED r2e_tests/test_1.py::test_str_params[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_params_on_redirect[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_fragment_on_redirect[pyloop]\nPASSED r2e_tests/test_1.py::test_drop_fragment[pyloop]\nPASSED r2e_tests/test_1.py::test_history[pyloop]\nPASSED r2e_tests/test_1.py::test_keepalive_closed_by_server[pyloop]\nPASSED r2e_tests/test_1.py::test_wait_for[pyloop]\nPASSED r2e_tests/test_1.py::test_raw_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_host_header_first[pyloop]\nPASSED r2e_tests/test_1.py::test_empty_header_values[pyloop]\nPASSED r2e_tests/test_1.py::test_204_with_gzipped_content_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_reading_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_conn_reading_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_session_read_timeout[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_between_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_on_reading_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_on_write[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_on_reading_data[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_none[pyloop]\nPASSED r2e_tests/test_1.py::test_readline_error_on_conn_close[pyloop]\nPASSED r2e_tests/test_1.py::test_no_error_on_conn_close_if_eof[pyloop]\nPASSED r2e_tests/test_1.py::test_error_not_overwrote_on_conn_close[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_OK_METHOD[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_OK_METHOD_connector[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_GET[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_HEAD[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_NON_HTTP[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_REDIRECT_POST_with_content_length_hdr[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_307_REDIRECT_POST[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_308_PERMANENT_REDIRECT_POST[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_302_max_redirects[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_GET_WITH_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_GET_WITH_MultiDict_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_HTTP_200_GET_WITH_MIXED_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_with_explicit_formdata[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_with_charset[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_formdats_with_charset[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_with_charset_post[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_MultiDict[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_DATA_DEFLATE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_DEFLATE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_bytes[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_bytes_too_large[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_STR[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_STR_SIMPLE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_LIST[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_CT[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_SINGLE[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_SINGLE_content_disposition[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_SINGLE_BINARY[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_IO[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_IO_WITH_PARAMS[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_FILES_WITH_DATA[pyloop]\nPASSED r2e_tests/test_1.py::test_POST_STREAM_DATA[pyloop]\nPASSED r2e_tests/test_1.py::test_json[pyloop]\nPASSED r2e_tests/test_1.py::test_json_custom[pyloop]\nPASSED r2e_tests/test_1.py::test_expect_continue[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_deflate[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_deflate_nochunk[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_gzip[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_gzip_write_by_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_encoding_gzip_nochunk[pyloop]\nPASSED r2e_tests/test_1.py::test_bad_payload_compression[pyloop]\nPASSED r2e_tests/test_1.py::test_bad_payload_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_no_payload_304_with_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_head_request_with_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_no_payload_200_with_chunked_encoding[pyloop]\nPASSED r2e_tests/test_1.py::test_bad_payload_content_length[pyloop]\nPASSED r2e_tests/test_1.py::test_payload_content_length_by_chunks[pyloop]\nPASSED r2e_tests/test_1.py::test_chunked[pyloop]\nPASSED r2e_tests/test_1.py::test_shortcuts[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies_per_request[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies_redirect[pyloop]\nPASSED r2e_tests/test_1.py::test_cookies_on_empty_session_jar[pyloop]\nPASSED r2e_tests/test_1.py::test_morsel_with_attributes[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies_expired[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies_max_age[pyloop]\nPASSED r2e_tests/test_1.py::test_set_cookies_max_age_overflow[pyloop]\nPASSED r2e_tests/test_1.py::test_request_conn_error\nPASSED r2e_tests/test_1.py::test_broken_connection_2[pyloop]\nPASSED r2e_tests/test_1.py::test_custom_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_redirect_to_absolute_url[pyloop]\nPASSED r2e_tests/test_1.py::test_redirect_without_location_header[pyloop]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http://:/-http://:/-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http:/-http:///-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http:/example.com-http:///example.com-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[http:///example.com-http:///example.com-InvalidUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[call:+380123456789-call:\\\\+380123456789-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[skype:handle-skype:handle-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[slack://instance/room-slack://instance/room-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[steam:code-steam:code-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[twitter://handle-twitter://handle-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_and_non_http_url[bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/-http:///-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/-http:///-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_invalid_redirect_url_multiple_redirects[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-200-True]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-201-True]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-301-True]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-400-False]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-403-False]\nPASSED r2e_tests/test_1.py::test_ok_from_status[pyloop-500-False]\nPASSED r2e_tests/test_1.py::test_raise_for_status[pyloop]\nPASSED r2e_tests/test_1.py::test_raise_for_status_per_request[pyloop]\nPASSED r2e_tests/test_1.py::test_raise_for_status_disable_per_request[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_default[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_disabled[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_enabled[pyloop]\nPASSED r2e_tests/test_1.py::test_session_raise_for_status_coro[pyloop]\nPASSED r2e_tests/test_1.py::test_request_raise_for_status_coro[pyloop]\nPASSED r2e_tests/test_1.py::test_invalid_idna\nPASSED r2e_tests/test_1.py::test_creds_in_auth_and_url\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts]\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-http -> https]\nPASSED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host[pyloop-https -> http]\nPASSED r2e_tests/test_1.py::test_auth_persist_on_redirect_to_other_host_with_global_auth[pyloop]\nPASSED r2e_tests/test_1.py::test_async_with_session\nPASSED r2e_tests/test_1.py::test_session_close_awaitable\nPASSED r2e_tests/test_1.py::test_close_resp_on_error_async_with_session[pyloop]\nPASSED r2e_tests/test_1.py::test_release_resp_on_normal_exit_from_cm[pyloop]\nPASSED r2e_tests/test_1.py::test_non_close_detached_session_on_error_cm[pyloop]\nPASSED r2e_tests/test_1.py::test_close_detached_session_on_non_existing_addr\nPASSED r2e_tests/test_1.py::test_aiohttp_request_context_manager[pyloop]\nPASSED r2e_tests/test_1.py::test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop]\nPASSED r2e_tests/test_1.py::test_aiohttp_request_ctx_manager_not_found\nPASSED r2e_tests/test_1.py::test_aiohttp_request_coroutine[pyloop]\nPASSED r2e_tests/test_1.py::test_yield_from_in_session_request[pyloop]\nPASSED r2e_tests/test_1.py::test_close_context_manager[pyloop]\nPASSED r2e_tests/test_1.py::test_session_auth[pyloop]\nPASSED r2e_tests/test_1.py::test_session_auth_override[pyloop]\nPASSED r2e_tests/test_1.py::test_session_auth_header_conflict[pyloop]\nPASSED r2e_tests/test_1.py::test_session_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_session_headers_merge[pyloop]\nPASSED r2e_tests/test_1.py::test_multidict_headers[pyloop]\nPASSED r2e_tests/test_1.py::test_request_conn_closed[pyloop]\nPASSED r2e_tests/test_1.py::test_dont_close_explicit_connector[pyloop]\nPASSED r2e_tests/test_1.py::test_server_close_keepalive_connection\nPASSED r2e_tests/test_1.py::test_handle_keepalive_on_closed_connection\nPASSED r2e_tests/test_1.py::test_error_in_performing_request[pyloop]\nPASSED r2e_tests/test_1.py::test_await_after_cancelling[pyloop]\nPASSED r2e_tests/test_1.py::test_async_payload_generator[pyloop]\nPASSED r2e_tests/test_1.py::test_read_from_closed_response[pyloop]\nPASSED r2e_tests/test_1.py::test_read_from_closed_response2[pyloop]\nPASSED r2e_tests/test_1.py::test_read_from_closed_content[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout[pyloop]\nPASSED r2e_tests/test_1.py::test_socket_timeout[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_closes_connection[pyloop]\nPASSED r2e_tests/test_1.py::test_read_timeout_on_prepared_response[pyloop]\nPASSED r2e_tests/test_1.py::test_timeout_with_full_buffer[pyloop]\nPASSED r2e_tests/test_1.py::test_read_bufsize_session_default[pyloop]\nPASSED r2e_tests/test_1.py::test_read_bufsize_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_http_empty_data_text[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_session_default[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_session_default_fail[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_session_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_max_field_size_request_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_session_default[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_session_default_fail[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_session_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_max_line_size_request_explicit[pyloop]\nPASSED r2e_tests/test_1.py::test_request_with_wrong_ssl_type[pyloop]\nPASSED r2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-42-TypeError]\nPASSED r2e_tests/test_1.py::test_request_with_wrong_proxy[pyloop-InvalidUrl-InvalidURL]\nPASSED r2e_tests/test_1.py::test_raise_for_status_is_none[pyloop]\nPASSED r2e_tests/test_1.py::test_exception_when_read_outside_of_session[pyloop]\nXFAIL r2e_tests/test_1.py::test_broken_connection[pyloop]\nXFAIL r2e_tests/test_1.py::test_rejected_upload[pyloop] - #7599\nXFAIL r2e_tests/test_1.py::test_header_too_large_error[pyloop] - #8395 Error message regression for large headers in 3.9.4\nFAILED r2e_tests/test_1.py::test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url[pyloop]\n================== 1 failed, 222 passed, 3 xfailed in 17.39s ===================\n",
    "old_commit_res_stderr": ""
}
CHANGES/8966.feature.rst aiohttp/client.py docs/client_reference.rst tests/test_client_functional.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Authorization Header Not Dropped on Redirect to Different Origin with Base URL Set

**Description:**
When a client session is configured with a base URL and global authentication, the `Authorization` header is not removed when a redirect leads to a different origin. This can result in unintended exposure of credentials to external hosts.

**Example Code:**
```python
import aiohttp
from aiohttp import web

async def handle_initial_request(request):
    # This handler redirects to a different host
    raise web.HTTPFound('http://host2.com/path2')

async def handle_redirected_request(request):
    # This handler expects the Authorization header to be absent
    if 'Authorization' in request.headers:
        raise web.HTTPInternalServerError()

async def main():
    # Setup server for host1.com
    app1 = web.Application()
    app1.router.add_get('/path1', handle_initial_request)
    runner1 = web.AppRunner(app1)
    await runner1.setup()
    site1 = web.TCPSite(runner1, 'host1.com', 8080)
    await site1.start()

    # Setup server for host2.com
    app2 = web.Application()
    app2.router.add_get('/path2', handle_redirected_request)
    runner2 = web.AppRunner(app2)
    await runner2.setup()
    site2 = web.TCPSite(runner2, 'host2.com', 8081)
    await site2.start()

    connector = aiohttp.TCPConnector()
    async with aiohttp.ClientSession(
        connector=connector,
        base_url='http://host1.com:8080',
        auth=aiohttp.BasicAuth('user', 'pass')
    ) as session:
        await session.get('/path1')  # This should drop the Authorization header on redirect

**Expected Behavior:**
When the client session follows a redirect to a different origin (`host2.com`), the `Authorization` header should be removed to prevent credential leakage. The redirected request to `http://host2.com/path2` should not include the `Authorization` header.

**Actual Behavior:**
The `Authorization` header is retained during the redirect, causing the assertion in the redirected request handler to fail and resulting in a `500 Internal Server Error`. This exposes sensitive authentication information to an unintended external host.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### aiohttp/client.py
"""HTTP Client for asyncio."""

import asyncio
import base64
import dataclasses
import hashlib
import json
import os
import sys
import traceback
import warnings
from contextlib import suppress
from types import TracebackType
from typing import (
    TYPE_CHECKING,
    Any,
    Awaitable,
    Callable,
    Collection,
    Coroutine,
    Final,
    FrozenSet,
    Generator,
    Generic,
    Iterable,
    List,
    Mapping,
    Optional,
    Set,
    Tuple,
    Type,
    TypedDict,
    TypeVar,
    Union,
    final,
)

from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr
from yarl import URL

from . import hdrs, http, payload
from .abc import AbstractCookieJar
from .client_exceptions import (
    ClientConnectionError,
    ClientConnectorCertificateError,
    ClientConnectorError,
    ClientConnectorSSLError,
    ClientError,
    ClientHttpProxyError,
    ClientOSError,
    ClientPayloadError,
    ClientProxyConnectionError,
    ClientResponseError,
    ClientSSLError,
    ConnectionTimeoutError,
    ContentTypeError,
    InvalidURL,
    InvalidUrlClientError,
    InvalidUrlRedirectClientError,
    NonHttpUrlClientError,
    NonHttpUrlRedirectClientError,
    RedirectClientError,
    ServerConnectionError,
    ServerDisconnectedError,
    ServerFingerprintMismatch,
    ServerTimeoutError,
    SocketTimeoutError,
    TooManyRedirects,
    WSServerHandshakeError,
)
from .client_reqrep import (
    SSL_ALLOWED_TYPES,
    ClientRequest,
    ClientResponse,
    Fingerprint,
    RequestInfo,
)
from .client_ws import (
    DEFAULT_WS_CLIENT_TIMEOUT,
    ClientWebSocketResponse,
    ClientWSTimeout,
)
from .connector import (
    HTTP_AND_EMPTY_SCHEMA_SET,
    BaseConnector,
    NamedPipeConnector,
    TCPConnector,
    UnixConnector,
)
from .cookiejar import CookieJar
from .helpers import (
    _SENTINEL,
    BasicAuth,
    TimeoutHandle,
    ceil_timeout,
    get_env_proxy_for_url,
    method_must_be_empty_body,
    sentinel,
    strip_auth_from_url,
)
from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter
from .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse
from .streams import FlowControlDataQueue
from .tracing import Trace, TraceConfig
from .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL

__all__ = (
    # client_exceptions
    "ClientConnectionError",
    "ClientConnectorCertificateError",
    "ClientConnectorError",
    "ClientConnectorSSLError",
    "ClientError",
    "ClientHttpProxyError",
    "ClientOSError",
    "ClientPayloadError",
    "ClientProxyConnectionError",
    "ClientResponseError",
    "ClientSSLError",
    "ConnectionTimeoutError",
    "ContentTypeError",
    "InvalidURL",
    "InvalidUrlClientError",
    "RedirectClientError",
    "NonHttpUrlClientError",
    "InvalidUrlRedirectClientError",
    "NonHttpUrlRedirectClientError",
    "ServerConnectionError",
    "ServerDisconnectedError",
    "ServerFingerprintMismatch",
    "ServerTimeoutError",
    "SocketTimeoutError",
    "TooManyRedirects",
    "WSServerHandshakeError",
    # client_reqrep
    "ClientRequest",
    "ClientResponse",
    "Fingerprint",
    "RequestInfo",
    # connector
    "BaseConnector",
    "TCPConnector",
    "UnixConnector",
    "NamedPipeConnector",
    # client_ws
    "ClientWebSocketResponse",
    # client
    "ClientSession",
    "ClientTimeout",
    "ClientWSTimeout",
    "request",
)


if TYPE_CHECKING:
    from ssl import SSLContext
else:
    SSLContext = None

if sys.version_info >= (3, 11) and TYPE_CHECKING:
    from typing import Unpack


class _RequestOptions(TypedDict, total=False):
    params: Union[Mapping[str, Union[str, int]], str, None]
    data: Any
    json: Any
    cookies: Union[LooseCookies, None]
    headers: Union[LooseHeaders, None]
    skip_auto_headers: Union[Iterable[str], None]
    auth: Union[BasicAuth, None]
    allow_redirects: bool
    max_redirects: int
    compress: Union[str, None]
    chunked: Union[bool, None]
    expect100: bool
    raise_for_status: Union[None, bool, Callable[[ClientResponse], Awaitable[None]]]
    read_until_eof: bool
    proxy: Union[StrOrURL, None]
    proxy_auth: Union[BasicAuth, None]
    timeout: "Union[ClientTimeout, _SENTINEL, None]"
    ssl: Union[SSLContext, bool, Fingerprint]
    server_hostname: Union[str, None]
    proxy_headers: Union[LooseHeaders, None]
    trace_request_ctx: Union[Mapping[str, str], None]
    read_bufsize: Union[int, None]
    auto_decompress: Union[bool, None]
    max_line_size: Union[int, None]
    max_field_size: Union[int, None]


@dataclasses.dataclass(frozen=True)
class ClientTimeout:
    total: Optional[float] = None
    connect: Optional[float] = None
    sock_read: Optional[float] = None
    sock_connect: Optional[float] = None
    ceil_threshold: float = 5

    # pool_queue_timeout: Optional[float] = None
    # dns_resolution_timeout: Optional[float] = None
    # socket_connect_timeout: Optional[float] = None
    # connection_acquiring_timeout: Optional[float] = None
    # new_connection_timeout: Optional[float] = None
    # http_header_timeout: Optional[float] = None
    # response_body_timeout: Optional[float] = None

    # to create a timeout specific for a single request, either
    # - create a completely new one to overwrite the default
    # - or use https://docs.python.org/3/library/dataclasses.html#dataclasses.replace
    # to overwrite the defaults


# 5 Minute default read timeout
DEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60)

# https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2
IDEMPOTENT_METHODS = frozenset({"GET", "HEAD", "OPTIONS", "TRACE", "PUT", "DELETE"})

_RetType = TypeVar("_RetType")
_CharsetResolver = Callable[[ClientResponse, bytes], str]


@final
class ClientSession:
    """First-class interface for making HTTP requests."""

    __slots__ = (
        "_base_url",
        "_source_traceback",
        "_connector",
        "_loop",
        "_cookie_jar",
        "_connector_owner",
        "_default_auth",
        "_version",
        "_json_serialize",
        "_requote_redirect_url",
        "_timeout",
        "_raise_for_status",
        "_auto_decompress",
        "_trust_env",
        "_default_headers",
        "_skip_auto_headers",
        "_request_class",
        "_response_class",
        "_ws_response_class",
        "_trace_configs",
        "_read_bufsize",
        "_max_line_size",
        "_max_field_size",
        "_resolve_charset",
    )

    def __init__(
        self,
        base_url: Optional[StrOrURL] = None,
        *,
        connector: Optional[BaseConnector] = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        json_serialize: JSONEncoder = json.dumps,
        request_class: Type[ClientRequest] = ClientRequest,
        response_class: Type[ClientResponse] = ClientResponse,
        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,
        version: HttpVersion = http.HttpVersion11,
        cookie_jar: Optional[AbstractCookieJar] = None,
        connector_owner: bool = True,
        raise_for_status: Union[
            bool, Callable[[ClientResponse], Awaitable[None]]
        ] = False,
        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,
        auto_decompress: bool = True,
        trust_env: bool = False,
        requote_redirect_url: bool = True,
        trace_configs: Optional[List[TraceConfig[object]]] = None,
        read_bufsize: int = 2**16,
        max_line_size: int = 8190,
        max_field_size: int = 8190,
        fallback_charset_resolver: _CharsetResolver = lambda r, b: "utf-8",
    ) -> None:
        # We initialise _connector to None immediately, as it's referenced in __del__()
        # and could cause issues if an exception occurs during initialisation.
        self._connector: Optional[BaseConnector] = None
        if base_url is None or isinstance(base_url, URL):
            self._base_url: Optional[URL] = base_url
        else:
            self._base_url = URL(base_url)
            assert (
                self._base_url.origin() == self._base_url
            ), "Only absolute URLs without path part are supported"

        loop = asyncio.get_running_loop()

        if timeout is sentinel or timeout is None:
            timeout = DEFAULT_TIMEOUT
        if not isinstance(timeout, ClientTimeout):
            raise ValueError(
                f"timeout parameter cannot be of {type(timeout)} type, "
                "please use 'timeout=ClientTimeout(...)'",
            )
        self._timeout = timeout

        if connector is None:
            connector = TCPConnector()
        # Initialize these three attrs before raising any exception,
        # they are used in __del__
        self._connector = connector
        self._loop = loop
        if loop.get_debug():
            self._source_traceback: Optional[traceback.StackSummary] = (
                traceback.extract_stack(sys._getframe(1))
            )
        else:
            self._source_traceback = None

        if connector._loop is not loop:
            raise RuntimeError("Session and connector have to use same event loop")

        if cookie_jar is None:
            cookie_jar = CookieJar()
        self._cookie_jar = cookie_jar

        if cookies is not None:
            self._cookie_jar.update_cookies(cookies)

        self._connector_owner = connector_owner
        self._default_auth = auth
        self._version = version
        self._json_serialize = json_serialize
        self._raise_for_status = raise_for_status
        self._auto_decompress = auto_decompress
        self._trust_env = trust_env
        self._requote_redirect_url = requote_redirect_url
        self._read_bufsize = read_bufsize
        self._max_line_size = max_line_size
        self._max_field_size = max_field_size

        # Convert to list of tuples
        if headers:
            real_headers: CIMultiDict[str] = CIMultiDict(headers)
        else:
            real_headers = CIMultiDict()
        self._default_headers: CIMultiDict[str] = real_headers
        if skip_auto_headers is not None:
            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)
        else:
            self._skip_auto_headers = frozenset()

        self._request_class = request_class
        self._response_class = response_class
        self._ws_response_class = ws_response_class

        self._trace_configs = trace_configs or []
        for trace_config in self._trace_configs:
            trace_config.freeze()

        self._resolve_charset = fallback_charset_resolver

    def __init_subclass__(cls: Type["ClientSession"]) -> None:
        raise TypeError(
            "Inheritance class {} from ClientSession "
            "is forbidden".format(cls.__name__)
        )

    def __del__(self, _warnings: Any = warnings) -> None:
        if not self.closed:
            _warnings.warn(
                f"Unclosed client session {self!r}",
                ResourceWarning,
                source=self,
            )
            context = {"client_session": self, "message": "Unclosed client session"}
            if self._source_traceback is not None:
                context["source_traceback"] = self._source_traceback
            self._loop.call_exception_handler(context)

    if sys.version_info >= (3, 11) and TYPE_CHECKING:

        def request(
            self,
            method: str,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

    else:

        def request(
            self, method: str, url: StrOrURL, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP request."""
            return _RequestContextManager(self._request(method, url, **kwargs))

    def _build_url(self, str_or_url: StrOrURL) -> URL:
        url = URL(str_or_url)
        if self._base_url is None:
            return url
        else:
            assert not url.is_absolute() and url.path.startswith("/")
            return self._base_url.join(url)

    async def _request(
        self,
        method: str,
        str_or_url: StrOrURL,
        *,
        params: Optional[Mapping[str, str]] = None,
        data: Any = None,
        json: Any = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        allow_redirects: bool = True,
        max_redirects: int = 10,
        compress: Optional[str] = None,
        chunked: Optional[bool] = None,
        expect100: bool = False,
        raise_for_status: Union[
            None, bool, Callable[[ClientResponse], Awaitable[None]]
        ] = None,
        read_until_eof: bool = True,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,
        ssl: Union[SSLContext, bool, Fingerprint] = True,
        server_hostname: Optional[str] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        trace_request_ctx: Optional[Mapping[str, str]] = None,
        read_bufsize: Optional[int] = None,
        auto_decompress: Optional[bool] = None,
        max_line_size: Optional[int] = None,
        max_field_size: Optional[int] = None,
    ) -> ClientResponse:
        # NOTE: timeout clamps existing connect and read timeouts.  We cannot
        # set the default to None because we need to detect if the user wants
        # to use the existing timeouts by setting timeout to None.

        if self.closed:
            raise RuntimeError("Session is closed")

        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, Fingerprint, or bool, "
                "got {!r} instead.".format(ssl)
            )

        if data is not None and json is not None:
            raise ValueError(
                "data and json parameters can not be used at the same time"
            )
        elif json is not None:
            data = payload.JsonPayload(json, dumps=self._json_serialize)

        redirects = 0
        history = []
        version = self._version
        params = params or {}

        # Merge with default headers and transform to CIMultiDict
        headers = self._prepare_headers(headers)
        proxy_headers = self._prepare_headers(proxy_headers)

        try:
            url = self._build_url(str_or_url)
        except ValueError as e:
            raise InvalidUrlClientError(str_or_url) from e

        assert self._connector is not None
        if url.scheme not in self._connector.allowed_protocol_schema_set:
            raise NonHttpUrlClientError(url)

        skip_headers = set(self._skip_auto_headers)
        if skip_auto_headers is not None:
            for i in skip_auto_headers:
                skip_headers.add(istr(i))

        if proxy is not None:
            try:
                proxy = URL(proxy)
            except ValueError as e:
                raise InvalidURL(proxy) from e

        if timeout is sentinel or timeout is None:
            real_timeout: ClientTimeout = self._timeout
        else:
            real_timeout = timeout
        # timeout is cumulative for all request operations
        # (request, redirects, responses, data consuming)
        tm = TimeoutHandle(
            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold
        )
        handle = tm.start()

        if read_bufsize is None:
            read_bufsize = self._read_bufsize

        if auto_decompress is None:
            auto_decompress = self._auto_decompress

        if max_line_size is None:
            max_line_size = self._max_line_size

        if max_field_size is None:
            max_field_size = self._max_field_size

        traces = [
            Trace(
                self,
                trace_config,
                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
            )
            for trace_config in self._trace_configs
        ]

        for trace in traces:
            await trace.send_request_start(method, url.update_query(params), headers)

        timer = tm.timer()
        try:
            with timer:
                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests
                retry_persistent_connection = method in IDEMPOTENT_METHODS
                while True:
                    url, auth_from_url = strip_auth_from_url(url)
                    if not url.raw_host:
                        # NOTE: Bail early, otherwise, causes `InvalidURL` through
                        # NOTE: `self._request_class()` below.
                        err_exc_cls = (
                            InvalidUrlRedirectClientError
                            if redirects
                            else InvalidUrlClientError
                        )
                        raise err_exc_cls(url)
                    if auth and auth_from_url:
                        raise ValueError(
                            "Cannot combine AUTH argument with "
                            "credentials encoded in URL"
                        )

                    if auth is None:
                        auth = auth_from_url
                    if auth is None:
                        auth = self._default_auth
                    # It would be confusing if we support explicit
                    # Authorization header with auth argument
                    if auth is not None and hdrs.AUTHORIZATION in headers:
                        raise ValueError(
                            "Cannot combine AUTHORIZATION header "
                            "with AUTH argument or credentials "
                            "encoded in URL"
                        )

                    all_cookies = self._cookie_jar.filter_cookies(url)

                    if cookies is not None:
                        tmp_cookie_jar = CookieJar()
                        tmp_cookie_jar.update_cookies(cookies)
                        req_cookies = tmp_cookie_jar.filter_cookies(url)
                        if req_cookies:
                            all_cookies.load(req_cookies)

                    if proxy is not None:
                        proxy = URL(proxy)
                    elif self._trust_env:
                        with suppress(LookupError):
                            proxy, proxy_auth = get_env_proxy_for_url(url)

                    req = self._request_class(
                        method,
                        url,
                        params=params,
                        headers=headers,
                        skip_auto_headers=skip_headers if skip_headers else None,
                        data=data,
                        cookies=all_cookies,
                        auth=auth,
                        version=version,
                        compress=compress,
                        chunked=chunked,
                        expect100=expect100,
                        loop=self._loop,
                        response_class=self._response_class,
                        proxy=proxy,
                        proxy_auth=proxy_auth,
                        timer=timer,
                        session=self,
                        ssl=ssl,
                        server_hostname=server_hostname,
                        proxy_headers=proxy_headers,
                        traces=traces,
                        trust_env=self.trust_env,
                    )

                    # connection timeout
                    try:
                        async with ceil_timeout(
                            real_timeout.connect,
                            ceil_threshold=real_timeout.ceil_threshold,
                        ):
                            conn = await self._connector.connect(
                                req, traces=traces, timeout=real_timeout
                            )
                    except asyncio.TimeoutError as exc:
                        raise ConnectionTimeoutError(
                            f"Connection timeout to host {url}"
                        ) from exc

                    assert conn.transport is not None

                    assert conn.protocol is not None
                    conn.protocol.set_response_params(
                        timer=timer,
                        skip_payload=method_must_be_empty_body(method),
                        read_until_eof=read_until_eof,
                        auto_decompress=auto_decompress,
                        read_timeout=real_timeout.sock_read,
                        read_bufsize=read_bufsize,
                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
                        max_line_size=max_line_size,
                        max_field_size=max_field_size,
                    )

                    try:
                        try:
                            resp = await req.send(conn)
                            try:
                                await resp.start(conn)
                            except BaseException:
                                resp.close()
                                raise
                        except BaseException:
                            conn.close()
                            raise
                    except (ClientOSError, ServerDisconnectedError):
                        if retry_persistent_connection:
                            retry_persistent_connection = False
                            continue
                        raise
                    except ClientError:
                        raise
                    except OSError as exc:
                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):
                            raise
                        raise ClientOSError(*exc.args) from exc

                    self._cookie_jar.update_cookies(resp.cookies, resp.url)

                    # redirects
                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:
                        for trace in traces:
                            await trace.send_request_redirect(
                                method, url.update_query(params), headers, resp
                            )

                        redirects += 1
                        history.append(resp)
                        if max_redirects and redirects >= max_redirects:
                            resp.close()
                            raise TooManyRedirects(
                                history[0].request_info, tuple(history)
                            )

                        # For 301 and 302, mimic IE, now changed in RFC
                        # https://github.com/kennethreitz/requests/pull/269
                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (
                            resp.status in (301, 302) and resp.method == hdrs.METH_POST
                        ):
                            method = hdrs.METH_GET
                            data = None
                            if headers.get(hdrs.CONTENT_LENGTH):
                                headers.pop(hdrs.CONTENT_LENGTH)

                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(
                            hdrs.URI
                        )
                        if r_url is None:
                            # see github.com/aio-libs/aiohttp/issues/2022
                            break
                        else:
                            # reading from correct redirection
                            # response is forbidden
                            resp.release()

                        try:
                            parsed_redirect_url = URL(
                                r_url, encoded=not self._requote_redirect_url
                            )
                        except ValueError as e:
                            raise InvalidUrlRedirectClientError(
                                r_url,
                                "Server attempted redirecting to a location that does not look like a URL",
                            ) from e

                        scheme = parsed_redirect_url.scheme
                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:
                            resp.close()
                            raise NonHttpUrlRedirectClientError(r_url)
                        elif not scheme:
                            parsed_redirect_url = url.join(parsed_redirect_url)

                        is_same_host_https_redirect = (
                            url.host == parsed_redirect_url.host
                            and parsed_redirect_url.scheme == "https"
                            and url.scheme == "http"
                        )

                        try:
                            redirect_origin = parsed_redirect_url.origin()
                        except ValueError as origin_val_err:
                            raise InvalidUrlRedirectClientError(
                                parsed_redirect_url,
                                "Invalid redirect URL origin",
                            ) from origin_val_err

                        if (
                            url.origin() != redirect_origin
                            and not is_same_host_https_redirect
                        ):
                            auth = None
                            headers.pop(hdrs.AUTHORIZATION, None)

                        url = parsed_redirect_url
                        params = {}
                        resp.release()
                        continue

                    break

            # check response status
            if raise_for_status is None:
                raise_for_status = self._raise_for_status

            if raise_for_status is None:
                pass
            elif callable(raise_for_status):
                await raise_for_status(resp)
            elif raise_for_status:
                resp.raise_for_status()

            # register connection
            if handle is not None:
                if resp.connection is not None:
                    resp.connection.add_callback(handle.cancel)
                else:
                    handle.cancel()

            resp._history = tuple(history)

            for trace in traces:
                await trace.send_request_end(
                    method, url.update_query(params), headers, resp
                )
            return resp

        except BaseException as e:
            # cleanup timer
            tm.close()
            if handle:
                handle.cancel()
                handle = None

            for trace in traces:
                await trace.send_request_exception(
                    method, url.update_query(params), headers, e
                )
            raise

    def ws_connect(
        self,
        url: StrOrURL,
        *,
        method: str = hdrs.METH_GET,
        protocols: Collection[str] = (),
        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,
        receive_timeout: Optional[float] = None,
        autoclose: bool = True,
        autoping: bool = True,
        heartbeat: Optional[float] = None,
        auth: Optional[BasicAuth] = None,
        origin: Optional[str] = None,
        params: Optional[Mapping[str, str]] = None,
        headers: Optional[LooseHeaders] = None,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        ssl: Union[SSLContext, bool, Fingerprint] = True,
        server_hostname: Optional[str] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        compress: int = 0,
        max_msg_size: int = 4 * 1024 * 1024,
    ) -> "_WSRequestContextManager":
        """Initiate websocket connection."""
        return _WSRequestContextManager(
            self._ws_connect(
                url,
                method=method,
                protocols=protocols,
                timeout=timeout,
                receive_timeout=receive_timeout,
                autoclose=autoclose,
                autoping=autoping,
                heartbeat=heartbeat,
                auth=auth,
                origin=origin,
                params=params,
                headers=headers,
                proxy=proxy,
                proxy_auth=proxy_auth,
                ssl=ssl,
                server_hostname=server_hostname,
                proxy_headers=proxy_headers,
                compress=compress,
                max_msg_size=max_msg_size,
            )
        )

    async def _ws_connect(
        self,
        url: StrOrURL,
        *,
        method: str = hdrs.METH_GET,
        protocols: Collection[str] = (),
        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,
        receive_timeout: Optional[float] = None,
        autoclose: bool = True,
        autoping: bool = True,
        heartbeat: Optional[float] = None,
        auth: Optional[BasicAuth] = None,
        origin: Optional[str] = None,
        params: Optional[Mapping[str, str]] = None,
        headers: Optional[LooseHeaders] = None,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        ssl: Union[SSLContext, bool, Fingerprint] = True,
        server_hostname: Optional[str] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        compress: int = 0,
        max_msg_size: int = 4 * 1024 * 1024,
    ) -> ClientWebSocketResponse:
        if timeout is sentinel or timeout is None:
            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT
        else:
            if isinstance(timeout, ClientWSTimeout):
                ws_timeout = timeout
            else:
                warnings.warn(
                    "parameter 'timeout' of type 'float' "
                    "is deprecated, please use "
                    "'timeout=ClientWSTimeout(ws_close=...)'",
                    DeprecationWarning,
                    stacklevel=2,
                )
                ws_timeout = ClientWSTimeout(ws_close=timeout)

        if receive_timeout is not None:
            warnings.warn(
                "float parameter 'receive_timeout' "
                "is deprecated, please use parameter "
                "'timeout=ClientWSTimeout(ws_receive=...)'",
                DeprecationWarning,
                stacklevel=2,
            )
            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)

        if headers is None:
            real_headers: CIMultiDict[str] = CIMultiDict()
        else:
            real_headers = CIMultiDict(headers)

        default_headers = {
            hdrs.UPGRADE: "websocket",
            hdrs.CONNECTION: "Upgrade",
            hdrs.SEC_WEBSOCKET_VERSION: "13",
        }

        for key, value in default_headers.items():
            real_headers.setdefault(key, value)

        sec_key = base64.b64encode(os.urandom(16))
        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()

        if protocols:
            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ",".join(protocols)
        if origin is not None:
            real_headers[hdrs.ORIGIN] = origin
        if compress:
            extstr = ws_ext_gen(compress=compress)
            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr

        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, Fingerprint, or bool, "
                "got {!r} instead.".format(ssl)
            )

        # send request
        resp = await self.request(
            method,
            url,
            params=params,
            headers=real_headers,
            read_until_eof=False,
            auth=auth,
            proxy=proxy,
            proxy_auth=proxy_auth,
            ssl=ssl,
            server_hostname=server_hostname,
            proxy_headers=proxy_headers,
        )

        try:
            # check handshake
            if resp.status != 101:
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid response status",
                    status=resp.status,
                    headers=resp.headers,
                )

            if resp.headers.get(hdrs.UPGRADE, "").lower() != "websocket":
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid upgrade header",
                    status=resp.status,
                    headers=resp.headers,
                )

            if resp.headers.get(hdrs.CONNECTION, "").lower() != "upgrade":
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid connection header",
                    status=resp.status,
                    headers=resp.headers,
                )

            # key calculation
            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, "")
            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()
            if r_key != match:
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid challenge response",
                    status=resp.status,
                    headers=resp.headers,
                )

            # websocket protocol
            protocol = None
            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:
                resp_protocols = [
                    proto.strip()
                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",")
                ]

                for proto in resp_protocols:
                    if proto in protocols:
                        protocol = proto
                        break

            # websocket compress
            notakeover = False
            if compress:
                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)
                if compress_hdrs:
                    try:
                        compress, notakeover = ws_ext_parse(compress_hdrs)
                    except WSHandshakeError as exc:
                        raise WSServerHandshakeError(
                            resp.request_info,
                            resp.history,
                            message=exc.args[0],
                            status=resp.status,
                            headers=resp.headers,
                        ) from exc
                else:
                    compress = 0
                    notakeover = False

            conn = resp.connection
            assert conn is not None
            conn_proto = conn.protocol
            assert conn_proto is not None

            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater
            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible
            if ws_timeout.ws_receive is None:
                # Reset regardless
                conn_proto.read_timeout = None
            elif conn_proto.read_timeout is not None:
                conn_proto.read_timeout = max(
                    ws_timeout.ws_receive, conn_proto.read_timeout
                )

            transport = conn.transport
            assert transport is not None
            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(
                conn_proto, 2**16, loop=self._loop
            )
            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)
            writer = WebSocketWriter(
                conn_proto,
                transport,
                use_mask=True,
                compress=compress,
                notakeover=notakeover,
            )
        except BaseException:
            resp.close()
            raise
        else:
            return self._ws_response_class(
                reader,
                writer,
                protocol,
                resp,
                ws_timeout,
                autoclose,
                autoping,
                self._loop,
                heartbeat=heartbeat,
                compress=compress,
                client_notakeover=notakeover,
            )

    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> "CIMultiDict[str]":
        """Add default headers and transform it to CIMultiDict"""
        # Convert headers to MultiDict
        result = CIMultiDict(self._default_headers)
        if headers:
            if not isinstance(headers, (MultiDictProxy, MultiDict)):
                headers = CIMultiDict(headers)
            added_names: Set[str] = set()
            for key, value in headers.items():
                if key in added_names:
                    result.add(key, value)
                else:
                    result[key] = value
                    added_names.add(key)
        return result

    if sys.version_info >= (3, 11) and TYPE_CHECKING:

        def get(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def options(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def head(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def post(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def put(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def patch(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def delete(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

    else:

        def get(
            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP GET request."""
            return _RequestContextManager(
                self._request(
                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs
                )
            )

        def options(
            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP OPTIONS request."""
            return _RequestContextManager(
                self._request(
                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs
                )
            )

        def head(
            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP HEAD request."""
            return _RequestContextManager(
                self._request(
                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs
                )
            )

        def post(
            self, url: StrOrURL, *, data: Any = None, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP POST request."""
            return _RequestContextManager(
                self._request(hdrs.METH_POST, url, data=data, **kwargs)
            )

        def put(
            self, url: StrOrURL, *, data: Any = None, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP PUT request."""
            return _RequestContextManager(
                self._request(hdrs.METH_PUT, url, data=data, **kwargs)
            )

        def patch(
            self, url: StrOrURL, *, data: Any = None, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP PATCH request."""
            return _RequestContextManager(
                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)
            )

        def delete(self, url: StrOrURL, **kwargs: Any) -> "_RequestContextManager":
            """Perform HTTP DELETE request."""
            return _RequestContextManager(
                self._request(hdrs.METH_DELETE, url, **kwargs)
            )

    async def close(self) -> None:
        """Close underlying connector.

        Release all acquired resources.
        """
        if not self.closed:
            if self._connector is not None and self._connector_owner:
                await self._connector.close()
            self._connector = None

    @property
    def closed(self) -> bool:
        """Is client session closed.

        A readonly property.
        """
        return self._connector is None or self._connector.closed

    @property
    def connector(self) -> Optional[BaseConnector]:
        """Connector instance used for the session."""
        return self._connector

    @property
    def cookie_jar(self) -> AbstractCookieJar:
        """The session cookies."""
        return self._cookie_jar

    @property
    def version(self) -> Tuple[int, int]:
        """The session HTTP protocol version."""
        return self._version

    @property
    def requote_redirect_url(self) -> bool:
        """Do URL requoting on redirection handling."""
        return self._requote_redirect_url

    @property
    def timeout(self) -> ClientTimeout:
        """Timeout for the session."""
        return self._timeout

    @property
    def headers(self) -> "CIMultiDict[str]":
        """The default headers of the client session."""
        return self._default_headers

    @property
    def skip_auto_headers(self) -> FrozenSet[istr]:
        """Headers for which autogeneration should be skipped"""
        return self._skip_auto_headers

    @property
    def auth(self) -> Optional[BasicAuth]:
        """An object that represents HTTP Basic Authorization"""
        return self._default_auth

    @property
    def json_serialize(self) -> JSONEncoder:
        """Json serializer callable"""
        return self._json_serialize

    @property
    def connector_owner(self) -> bool:
        """Should connector be closed on session closing"""
        return self._connector_owner

    @property
    def raise_for_status(
        self,
    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:
        """Should `ClientResponse.raise_for_status()` be called for each response."""
        return self._raise_for_status

    @property
    def auto_decompress(self) -> bool:
        """Should the body response be automatically decompressed."""
        return self._auto_decompress

    @property
    def trust_env(self) -> bool:
        """
        Should proxies information from environment or netrc be trusted.

        Information is from HTTP_PROXY / HTTPS_PROXY environment variables
        or ~/.netrc file if present.
        """
        return self._trust_env

    @property
    def trace_configs(self) -> List[TraceConfig[Any]]:
        """A list of TraceConfig instances used for client tracing"""
        return self._trace_configs

    def detach(self) -> None:
        """Detach connector from session without closing the former.

        Session is switched to closed state anyway.
        """
        self._connector = None

    async def __aenter__(self) -> "ClientSession":
        return self

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        await self.close()


class _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]):
    __slots__ = ("_coro", "_resp")

    def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> None:
        self._coro = coro

    def send(self, arg: None) -> "asyncio.Future[Any]":
        return self._coro.send(arg)

    def throw(self, *args: Any, **kwargs: Any) -> "asyncio.Future[Any]":
        return self._coro.throw(*args, **kwargs)

    def close(self) -> None:
        return self._coro.close()

    def __await__(self) -> Generator[Any, None, _RetType]:
        ret = self._coro.__await__()
        return ret

    def __iter__(self) -> Generator[Any, None, _RetType]:
        return self.__await__()

    async def __aenter__(self) -> _RetType:
        self._resp = await self._coro
        return self._resp


class _RequestContextManager(_BaseRequestContextManager[ClientResponse]):
    __slots__ = ()

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ) -> None:
        # We're basing behavior on the exception as it can be caused by
        # user code unrelated to the status of the connection.  If you
        # would like to close a connection you must do that
        # explicitly.  Otherwise connection error handling should kick in
        # and close/recycle the connection as required.
        self._resp.release()
        await self._resp.wait_for_close()


class _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]):
    __slots__ = ()

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ) -> None:
        await self._resp.close()


class _SessionRequestContextManager:
    __slots__ = ("_coro", "_resp", "_session")

    def __init__(
        self,
        coro: Coroutine["asyncio.Future[Any]", None, ClientResponse],
        session: ClientSession,
    ) -> None:
        self._coro = coro
        self._resp: Optional[ClientResponse] = None
        self._session = session

    async def __aenter__(self) -> ClientResponse:
        try:
            self._resp = await self._coro
        except BaseException:
            await self._session.close()
            raise
        else:
            return self._resp

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ) -> None:
        assert self._resp is not None
        self._resp.close()
        await self._session.close()


def request(
    method: str,
    url: StrOrURL,
    *,
    params: Optional[Mapping[str, str]] = None,
    data: Any = None,
    json: Any = None,
    headers: Optional[LooseHeaders] = None,
    skip_auto_headers: Optional[Iterable[str]] = None,
    auth: Optional[BasicAuth] = None,
    allow_redirects: bool = True,
    max_redirects: int = 10,
    compress: Optional[str] = None,
    chunked: Optional[bool] = None,
    expect100: bool = False,
    raise_for_status: Optional[bool] = None,
    read_until_eof: bool = True,
    proxy: Optional[StrOrURL] = None,
    proxy_auth: Optional[BasicAuth] = None,
    timeout: Union[ClientTimeout, _SENTINEL] = sentinel,
    cookies: Optional[LooseCookies] = None,
    version: HttpVersion = http.HttpVersion11,
    connector: Optional[BaseConnector] = None,
    read_bufsize: Optional[int] = None,
    max_line_size: int = 8190,
    max_field_size: int = 8190,
) -> _SessionRequestContextManager:
    """Constructs and sends a request.

    Returns response object.
    method - HTTP method
    url - request url
    params - (optional) Dictionary or bytes to be sent in the query
      string of the new request
    data - (optional) Dictionary, bytes, or file-like object to
      send in the body of the request
    json - (optional) Any json compatible python object
    headers - (optional) Dictionary of HTTP Headers to send with
      the request
    cookies - (optional) Dict object to send with the request
    auth - (optional) BasicAuth named tuple represent HTTP Basic Auth
    auth - aiohttp.helpers.BasicAuth
    allow_redirects - (optional) If set to False, do not follow
      redirects
    version - Request HTTP version.
    compress - Set to True if request has to be compressed
       with deflate encoding.
    chunked - Set to chunk size for chunked transfer encoding.
    expect100 - Expect 100-continue response from server.
    connector - BaseConnector sub-class instance to support
       connection pooling.
    read_until_eof - Read response until eof if response
       does not have Content-Length header.
    loop - Optional event loop.
    timeout - Optional ClientTimeout settings structure, 5min
       total timeout by default.
    Usage::
      >>> import aiohttp
      >>> async with aiohttp.request('GET', 'http://python.org/') as resp:
      ...    print(resp)
      ...    data = await resp.read()
      <ClientResponse(https://www.python.org/) [200 OK]>
    """
    connector_owner = False
    if connector is None:
        connector_owner = True
        connector = TCPConnector(force_close=True)

    session = ClientSession(
        cookies=cookies,
        version=version,
        timeout=timeout,
        connector=connector,
        connector_owner=connector_owner,
    )

    return _SessionRequestContextManager(
        session._request(
            method,
            url,
            params=params,
            data=data,
            json=json,
            headers=headers,
            skip_auto_headers=skip_auto_headers,
            auth=auth,
            allow_redirects=allow_redirects,
            max_redirects=max_redirects,
            compress=compress,
            chunked=chunked,
            expect100=expect100,
            raise_for_status=raise_for_status,
            read_until_eof=read_until_eof,
            proxy=proxy,
            proxy_auth=proxy_auth,
            read_bufsize=read_bufsize,
            max_line_size=max_line_size,
            max_field_size=max_field_size,
        ),
        session,
    )

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Title:** Authorization Header Not Dropped on Redirect to Different Origin with Base URL Set

**Description:**
When a client session is configured with a base URL and global authentication, the `Authorization` header is not removed when a redirect leads to a different origin. This can result in unintended exposure of credentials to external hosts.

**Example Code:**
```python
import aiohttp
from aiohttp import web

async def handle_initial_request(request):
    # This handler redirects to a different host
    raise web.HTTPFound('http://host2.com/path2')

async def handle_redirected_request(request):
    # This handler expects the Authorization header to be absent
    if 'Authorization' in request.headers:
        raise web.HTTPInternalServerError()

async def main():
    # Setup server for host1.com
    app1 = web.Application()
    app1.router.add_get('/path1', handle_initial_request)
    runner1 = web.AppRunner(app1)
    await runner1.setup()
    site1 = web.TCPSite(runner1, 'host1.com', 8080)
    await site1.start()

    # Setup server for host2.com
    app2 = web.Application()
    app2.router.add_get('/path2', handle_redirected_request)
    runner2 = web.AppRunner(app2)
    await runner2.setup()
    site2 = web.TCPSite(runner2, 'host2.com', 8081)
    await site2.start()

    connector = aiohttp.TCPConnector()
    async with aiohttp.ClientSession(
        connector=connector,
        base_url='http://host1.com:8080',
        auth=aiohttp.BasicAuth('user', 'pass')
    ) as session:
        await session.get('/path1')  # This should drop the Authorization header on redirect

**Expected Behavior:**
When the client session follows a redirect to a different origin (`host2.com`), the `Authorization` header should be removed to prevent credential leakage. The redirected request to `http://host2.com/path2` should not include the `Authorization` header.

**Actual Behavior:**
The `Authorization` header is retained during the redirect, causing the assertion in the redirected request handler to fail and resulting in a `500 Internal Server Error`. This exposes sensitive authentication information to an unintended external host.
[/ISSUE]
{
    "test_keepalive_two_requests_success[pyloop]": "PASSED",
    "test_keepalive_after_head_requests_success[pyloop]": "PASSED",
    "test_keepalive_after_empty_body_status[pyloop-101]": "PASSED",
    "test_keepalive_after_empty_body_status[pyloop-204]": "PASSED",
    "test_keepalive_after_empty_body_status[pyloop-304]": "PASSED",
    "test_keepalive_after_empty_body_status_stream_response[pyloop-101]": "PASSED",
    "test_keepalive_after_empty_body_status_stream_response[pyloop-204]": "PASSED",
    "test_keepalive_after_empty_body_status_stream_response[pyloop-304]": "PASSED",
    "test_keepalive_response_released[pyloop]": "PASSED",
    "test_upgrade_connection_not_released_after_read[pyloop]": "PASSED",
    "test_keepalive_server_force_close_connection[pyloop]": "PASSED",
    "test_keepalive_timeout_async_sleep": "PASSED",
    "test_keepalive_timeout_sync_sleep": "PASSED",
    "test_release_early[pyloop]": "PASSED",
    "test_HTTP_304[pyloop]": "PASSED",
    "test_stream_request_on_server_eof[pyloop]": "PASSED",
    "test_stream_request_on_server_eof_nested[pyloop]": "PASSED",
    "test_HTTP_304_WITH_BODY[pyloop]": "PASSED",
    "test_auto_header_user_agent[pyloop]": "PASSED",
    "test_skip_auto_headers_user_agent[pyloop]": "PASSED",
    "test_skip_default_auto_headers_user_agent[pyloop]": "PASSED",
    "test_skip_auto_headers_content_type[pyloop]": "PASSED",
    "test_post_data_bytesio[pyloop]": "PASSED",
    "test_post_data_with_bytesio_file[pyloop]": "PASSED",
    "test_post_data_stringio[pyloop]": "PASSED",
    "test_post_data_textio_encoding[pyloop]": "PASSED",
    "test_post_data_zipfile_filelike[pyloop]": "PASSED",
    "test_post_data_tarfile_filelike[pyloop]": "PASSED",
    "test_ssl_client[pyloop]": "PASSED",
    "test_tcp_connector_fingerprint_ok[pyloop]": "PASSED",
    "test_tcp_connector_fingerprint_fail[pyloop]": "PASSED",
    "test_format_task_get[pyloop]": "PASSED",
    "test_str_params[pyloop]": "PASSED",
    "test_drop_params_on_redirect[pyloop]": "PASSED",
    "test_drop_fragment_on_redirect[pyloop]": "PASSED",
    "test_drop_fragment[pyloop]": "PASSED",
    "test_history[pyloop]": "PASSED",
    "test_keepalive_closed_by_server[pyloop]": "PASSED",
    "test_wait_for[pyloop]": "PASSED",
    "test_raw_headers[pyloop]": "PASSED",
    "test_host_header_first[pyloop]": "PASSED",
    "test_empty_header_values[pyloop]": "PASSED",
    "test_204_with_gzipped_content_encoding[pyloop]": "PASSED",
    "test_timeout_on_reading_headers[pyloop]": "PASSED",
    "test_timeout_on_conn_reading_headers[pyloop]": "PASSED",
    "test_timeout_on_session_read_timeout[pyloop]": "PASSED",
    "test_read_timeout_between_chunks[pyloop]": "PASSED",
    "test_read_timeout_on_reading_chunks[pyloop]": "PASSED",
    "test_read_timeout_on_write[pyloop]": "PASSED",
    "test_timeout_on_reading_data[pyloop]": "PASSED",
    "test_timeout_none[pyloop]": "PASSED",
    "test_readline_error_on_conn_close[pyloop]": "PASSED",
    "test_no_error_on_conn_close_if_eof[pyloop]": "PASSED",
    "test_error_not_overwrote_on_conn_close[pyloop]": "PASSED",
    "test_HTTP_200_OK_METHOD[pyloop]": "PASSED",
    "test_HTTP_200_OK_METHOD_connector[pyloop]": "PASSED",
    "test_HTTP_302_REDIRECT_GET[pyloop]": "PASSED",
    "test_HTTP_302_REDIRECT_HEAD[pyloop]": "PASSED",
    "test_HTTP_302_REDIRECT_NON_HTTP[pyloop]": "PASSED",
    "test_HTTP_302_REDIRECT_POST[pyloop]": "PASSED",
    "test_HTTP_302_REDIRECT_POST_with_content_length_hdr[pyloop]": "PASSED",
    "test_HTTP_307_REDIRECT_POST[pyloop]": "PASSED",
    "test_HTTP_308_PERMANENT_REDIRECT_POST[pyloop]": "PASSED",
    "test_HTTP_302_max_redirects[pyloop]": "PASSED",
    "test_HTTP_200_GET_WITH_PARAMS[pyloop]": "PASSED",
    "test_HTTP_200_GET_WITH_MultiDict_PARAMS[pyloop]": "PASSED",
    "test_HTTP_200_GET_WITH_MIXED_PARAMS[pyloop]": "PASSED",
    "test_POST_DATA[pyloop]": "PASSED",
    "test_POST_DATA_with_explicit_formdata[pyloop]": "PASSED",
    "test_POST_DATA_with_charset[pyloop]": "PASSED",
    "test_POST_DATA_formdats_with_charset[pyloop]": "PASSED",
    "test_POST_DATA_with_charset_post[pyloop]": "PASSED",
    "test_POST_MultiDict[pyloop]": "PASSED",
    "test_POST_DATA_DEFLATE[pyloop]": "PASSED",
    "test_POST_FILES[pyloop]": "PASSED",
    "test_POST_FILES_DEFLATE[pyloop]": "PASSED",
    "test_POST_bytes[pyloop]": "PASSED",
    "test_POST_bytes_too_large[pyloop]": "PASSED",
    "test_POST_FILES_STR[pyloop]": "PASSED",
    "test_POST_FILES_STR_SIMPLE[pyloop]": "PASSED",
    "test_POST_FILES_LIST[pyloop]": "PASSED",
    "test_POST_FILES_CT[pyloop]": "PASSED",
    "test_POST_FILES_SINGLE[pyloop]": "PASSED",
    "test_POST_FILES_SINGLE_content_disposition[pyloop]": "PASSED",
    "test_POST_FILES_SINGLE_BINARY[pyloop]": "PASSED",
    "test_POST_FILES_IO[pyloop]": "PASSED",
    "test_POST_FILES_IO_WITH_PARAMS[pyloop]": "PASSED",
    "test_POST_FILES_WITH_DATA[pyloop]": "PASSED",
    "test_POST_STREAM_DATA[pyloop]": "PASSED",
    "test_json[pyloop]": "PASSED",
    "test_json_custom[pyloop]": "PASSED",
    "test_expect_continue[pyloop]": "PASSED",
    "test_encoding_deflate[pyloop]": "PASSED",
    "test_encoding_deflate_nochunk[pyloop]": "PASSED",
    "test_encoding_gzip[pyloop]": "PASSED",
    "test_encoding_gzip_write_by_chunks[pyloop]": "PASSED",
    "test_encoding_gzip_nochunk[pyloop]": "PASSED",
    "test_bad_payload_compression[pyloop]": "PASSED",
    "test_bad_payload_chunked_encoding[pyloop]": "PASSED",
    "test_no_payload_304_with_chunked_encoding[pyloop]": "PASSED",
    "test_head_request_with_chunked_encoding[pyloop]": "PASSED",
    "test_no_payload_200_with_chunked_encoding[pyloop]": "PASSED",
    "test_bad_payload_content_length[pyloop]": "PASSED",
    "test_payload_content_length_by_chunks[pyloop]": "PASSED",
    "test_chunked[pyloop]": "PASSED",
    "test_shortcuts[pyloop]": "PASSED",
    "test_cookies[pyloop]": "PASSED",
    "test_cookies_per_request[pyloop]": "PASSED",
    "test_cookies_redirect[pyloop]": "PASSED",
    "test_cookies_on_empty_session_jar[pyloop]": "PASSED",
    "test_morsel_with_attributes[pyloop]": "PASSED",
    "test_set_cookies[pyloop]": "PASSED",
    "test_set_cookies_expired[pyloop]": "PASSED",
    "test_set_cookies_max_age[pyloop]": "PASSED",
    "test_set_cookies_max_age_overflow[pyloop]": "PASSED",
    "test_request_conn_error": "PASSED",
    "test_broken_connection_2[pyloop]": "PASSED",
    "test_custom_headers[pyloop]": "PASSED",
    "test_redirect_to_absolute_url[pyloop]": "PASSED",
    "test_redirect_without_location_header[pyloop]": "PASSED",
    "test_invalid_and_non_http_url[http://:/-http://:/-InvalidUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[http:/-http:///-InvalidUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[http:/example.com-http:///example.com-InvalidUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[http:///example.com-http:///example.com-InvalidUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[call:+380123456789-call:\\\\+380123456789-NonHttpUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[skype:handle-skype:handle-NonHttpUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[slack://instance/room-slack://instance/room-NonHttpUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[steam:code-steam:code-NonHttpUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[twitter://handle-twitter://handle-NonHttpUrlClientError]": "PASSED",
    "test_invalid_and_non_http_url[bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-http:/-http:///-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-http:/-http:///-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-http:/example.com-http:///example.com-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-http:///example.com-http:///example.com-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-http://:/-http://:/-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-http://example.org:non_int_port/-http://example.org:non_int_port/-InvalidUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-call:+380123456789-call:\\\\+380123456789-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-skype:handle-skype:handle-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-slack://instance/room-slack://instance/room-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-steam:code-steam:code-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-twitter://handle-twitter://handle-NonHttpUrlRedirectClientError]": "PASSED",
    "test_invalid_redirect_url_multiple_redirects[pyloop-bluesky://profile/d:i:d-bluesky://profile/d:i:d-NonHttpUrlRedirectClientError]": "PASSED",
    "test_ok_from_status[pyloop-200-True]": "PASSED",
    "test_ok_from_status[pyloop-201-True]": "PASSED",
    "test_ok_from_status[pyloop-301-True]": "PASSED",
    "test_ok_from_status[pyloop-400-False]": "PASSED",
    "test_ok_from_status[pyloop-403-False]": "PASSED",
    "test_ok_from_status[pyloop-500-False]": "PASSED",
    "test_raise_for_status[pyloop]": "PASSED",
    "test_raise_for_status_per_request[pyloop]": "PASSED",
    "test_raise_for_status_disable_per_request[pyloop]": "PASSED",
    "test_request_raise_for_status_default[pyloop]": "PASSED",
    "test_request_raise_for_status_disabled[pyloop]": "PASSED",
    "test_request_raise_for_status_enabled[pyloop]": "PASSED",
    "test_session_raise_for_status_coro[pyloop]": "PASSED",
    "test_request_raise_for_status_coro[pyloop]": "PASSED",
    "test_invalid_idna": "PASSED",
    "test_creds_in_auth_and_url": "PASSED",
    "test_drop_auth_on_redirect_to_other_host[pyloop-entirely different hosts]": "PASSED",
    "test_drop_auth_on_redirect_to_other_host[pyloop-http -> https]": "PASSED",
    "test_drop_auth_on_redirect_to_other_host[pyloop-https -> http]": "PASSED",
    "test_auth_persist_on_redirect_to_other_host_with_global_auth[pyloop]": "PASSED",
    "test_drop_auth_on_redirect_to_other_host_with_global_auth_and_base_url[pyloop]": "PASSED",
    "test_async_with_session": "PASSED",
    "test_session_close_awaitable": "PASSED",
    "test_close_resp_on_error_async_with_session[pyloop]": "PASSED",
    "test_release_resp_on_normal_exit_from_cm[pyloop]": "PASSED",
    "test_non_close_detached_session_on_error_cm[pyloop]": "PASSED",
    "test_close_detached_session_on_non_existing_addr": "PASSED",
    "test_aiohttp_request_context_manager[pyloop]": "PASSED",
    "test_aiohttp_request_ctx_manager_close_sess_on_error[pyloop]": "PASSED",
    "test_aiohttp_request_ctx_manager_not_found": "PASSED",
    "test_aiohttp_request_coroutine[pyloop]": "PASSED",
    "test_yield_from_in_session_request[pyloop]": "PASSED",
    "test_close_context_manager[pyloop]": "PASSED",
    "test_session_auth[pyloop]": "PASSED",
    "test_session_auth_override[pyloop]": "PASSED",
    "test_session_auth_header_conflict[pyloop]": "PASSED",
    "test_session_headers[pyloop]": "PASSED",
    "test_session_headers_merge[pyloop]": "PASSED",
    "test_multidict_headers[pyloop]": "PASSED",
    "test_request_conn_closed[pyloop]": "PASSED",
    "test_dont_close_explicit_connector[pyloop]": "PASSED",
    "test_server_close_keepalive_connection": "PASSED",
    "test_handle_keepalive_on_closed_connection": "PASSED",
    "test_error_in_performing_request[pyloop]": "PASSED",
    "test_await_after_cancelling[pyloop]": "PASSED",
    "test_async_payload_generator[pyloop]": "PASSED",
    "test_read_from_closed_response[pyloop]": "PASSED",
    "test_read_from_closed_response2[pyloop]": "PASSED",
    "test_read_from_closed_content[pyloop]": "PASSED",
    "test_read_timeout[pyloop]": "PASSED",
    "test_socket_timeout[pyloop]": "PASSED",
    "test_read_timeout_closes_connection[pyloop]": "PASSED",
    "test_read_timeout_on_prepared_response[pyloop]": "PASSED",
    "test_timeout_with_full_buffer[pyloop]": "PASSED",
    "test_read_bufsize_session_default[pyloop]": "PASSED",
    "test_read_bufsize_explicit[pyloop]": "PASSED",
    "test_http_empty_data_text[pyloop]": "PASSED",
    "test_max_field_size_session_default[pyloop]": "PASSED",
    "test_max_field_size_session_default_fail[pyloop]": "PASSED",
    "test_max_field_size_session_explicit[pyloop]": "PASSED",
    "test_max_field_size_request_explicit[pyloop]": "PASSED",
    "test_max_line_size_session_default[pyloop]": "PASSED",
    "test_max_line_size_session_default_fail[pyloop]": "PASSED",
    "test_max_line_size_session_explicit[pyloop]": "PASSED",
    "test_max_line_size_request_explicit[pyloop]": "PASSED",
    "test_request_with_wrong_ssl_type[pyloop]": "PASSED",
    "test_request_with_wrong_proxy[pyloop-42-TypeError]": "PASSED",
    "test_request_with_wrong_proxy[pyloop-InvalidUrl-InvalidURL]": "PASSED",
    "test_raise_for_status_is_none[pyloop]": "PASSED",
    "test_exception_when_read_outside_of_session[pyloop]": "PASSED"
}
diff --git a/aiohttp/client.py b/aiohttp/client.py
index e3e9b29d..4e2faa1a 100644
--- a/aiohttp/client.py
+++ b/aiohttp/client.py
@@ -543,7 +543,10 @@ class ClientSession:
 
                     if auth is None:
                         auth = auth_from_url
-                    if auth is None:
+
+                    if auth is None and (
+                        not self._base_url or self._base_url.origin() == url.origin()
+                    ):
                         auth = self._default_auth
                     # It would be confusing if we support explicit
                     # Authorization header with auth argument

{"aiohttp/client.py": "\"\"\"HTTP Client for asyncio.\"\"\"\n\nimport asyncio\nimport base64\nimport dataclasses\nimport hashlib\nimport json\nimport os\nimport sys\nimport traceback\nimport warnings\nfrom contextlib import suppress\nfrom types import TracebackType\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Awaitable,\n    Callable,\n    Collection,\n    Coroutine,\n    Final,\n    FrozenSet,\n    Generator,\n    Generic,\n    Iterable,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n    TypedDict,\n    TypeVar,\n    Union,\n    final,\n)\n\nfrom multidict import CIMultiDict, MultiDict, MultiDictProxy, istr\nfrom yarl import URL\n\nfrom . import hdrs, http, payload\nfrom .abc import AbstractCookieJar\nfrom .client_exceptions import (\n    ClientConnectionError,\n    ClientConnectorCertificateError,\n    ClientConnectorError,\n    ClientConnectorSSLError,\n    ClientError,\n    ClientHttpProxyError,\n    ClientOSError,\n    ClientPayloadError,\n    ClientProxyConnectionError,\n    ClientResponseError,\n    ClientSSLError,\n    ConnectionTimeoutError,\n    ContentTypeError,\n    InvalidURL,\n    InvalidUrlClientError,\n    InvalidUrlRedirectClientError,\n    NonHttpUrlClientError,\n    NonHttpUrlRedirectClientError,\n    RedirectClientError,\n    ServerConnectionError,\n    ServerDisconnectedError,\n    ServerFingerprintMismatch,\n    ServerTimeoutError,\n    SocketTimeoutError,\n    TooManyRedirects,\n    WSServerHandshakeError,\n)\nfrom .client_reqrep import (\n    SSL_ALLOWED_TYPES,\n    ClientRequest,\n    ClientResponse,\n    Fingerprint,\n    RequestInfo,\n)\nfrom .client_ws import (\n    DEFAULT_WS_CLIENT_TIMEOUT,\n    ClientWebSocketResponse,\n    ClientWSTimeout,\n)\nfrom .connector import (\n    HTTP_AND_EMPTY_SCHEMA_SET,\n    BaseConnector,\n    NamedPipeConnector,\n    TCPConnector,\n    UnixConnector,\n)\nfrom .cookiejar import CookieJar\nfrom .helpers import (\n    _SENTINEL,\n    BasicAuth,\n    TimeoutHandle,\n    ceil_timeout,\n    get_env_proxy_for_url,\n    method_must_be_empty_body,\n    sentinel,\n    strip_auth_from_url,\n)\nfrom .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter\nfrom .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse\nfrom .streams import FlowControlDataQueue\nfrom .tracing import Trace, TraceConfig\nfrom .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL\n\n__all__ = (\n    # client_exceptions\n    \"ClientConnectionError\",\n    \"ClientConnectorCertificateError\",\n    \"ClientConnectorError\",\n    \"ClientConnectorSSLError\",\n    \"ClientError\",\n    \"ClientHttpProxyError\",\n    \"ClientOSError\",\n    \"ClientPayloadError\",\n    \"ClientProxyConnectionError\",\n    \"ClientResponseError\",\n    \"ClientSSLError\",\n    \"ConnectionTimeoutError\",\n    \"ContentTypeError\",\n    \"InvalidURL\",\n    \"InvalidUrlClientError\",\n    \"RedirectClientError\",\n    \"NonHttpUrlClientError\",\n    \"InvalidUrlRedirectClientError\",\n    \"NonHttpUrlRedirectClientError\",\n    \"ServerConnectionError\",\n    \"ServerDisconnectedError\",\n    \"ServerFingerprintMismatch\",\n    \"ServerTimeoutError\",\n    \"SocketTimeoutError\",\n    \"TooManyRedirects\",\n    \"WSServerHandshakeError\",\n    # client_reqrep\n    \"ClientRequest\",\n    \"ClientResponse\",\n    \"Fingerprint\",\n    \"RequestInfo\",\n    # connector\n    \"BaseConnector\",\n    \"TCPConnector\",\n    \"UnixConnector\",\n    \"NamedPipeConnector\",\n    # client_ws\n    \"ClientWebSocketResponse\",\n    # client\n    \"ClientSession\",\n    \"ClientTimeout\",\n    \"ClientWSTimeout\",\n    \"request\",\n)\n\n\nif TYPE_CHECKING:\n    from ssl import SSLContext\nelse:\n    SSLContext = None\n\nif sys.version_info >= (3, 11) and TYPE_CHECKING:\n    from typing import Unpack\n\n\nclass _RequestOptions(TypedDict, total=False):\n    params: Union[Mapping[str, Union[str, int]], str, None]\n    data: Any\n    json: Any\n    cookies: Union[LooseCookies, None]\n    headers: Union[LooseHeaders, None]\n    skip_auto_headers: Union[Iterable[str], None]\n    auth: Union[BasicAuth, None]\n    allow_redirects: bool\n    max_redirects: int\n    compress: Union[str, None]\n    chunked: Union[bool, None]\n    expect100: bool\n    raise_for_status: Union[None, bool, Callable[[ClientResponse], Awaitable[None]]]\n    read_until_eof: bool\n    proxy: Union[StrOrURL, None]\n    proxy_auth: Union[BasicAuth, None]\n    timeout: \"Union[ClientTimeout, _SENTINEL, None]\"\n    ssl: Union[SSLContext, bool, Fingerprint]\n    server_hostname: Union[str, None]\n    proxy_headers: Union[LooseHeaders, None]\n    trace_request_ctx: Union[Mapping[str, str], None]\n    read_bufsize: Union[int, None]\n    auto_decompress: Union[bool, None]\n    max_line_size: Union[int, None]\n    max_field_size: Union[int, None]\n\n\n@dataclasses.dataclass(frozen=True)\nclass ClientTimeout:\n    total: Optional[float] = None\n    connect: Optional[float] = None\n    sock_read: Optional[float] = None\n    sock_connect: Optional[float] = None\n    ceil_threshold: float = 5\n\n    # pool_queue_timeout: Optional[float] = None\n    # dns_resolution_timeout: Optional[float] = None\n    # socket_connect_timeout: Optional[float] = None\n    # connection_acquiring_timeout: Optional[float] = None\n    # new_connection_timeout: Optional[float] = None\n    # http_header_timeout: Optional[float] = None\n    # response_body_timeout: Optional[float] = None\n\n    # to create a timeout specific for a single request, either\n    # - create a completely new one to overwrite the default\n    # - or use https://docs.python.org/3/library/dataclasses.html#dataclasses.replace\n    # to overwrite the defaults\n\n\n# 5 Minute default read timeout\nDEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60)\n\n# https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2\nIDEMPOTENT_METHODS = frozenset({\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\", \"PUT\", \"DELETE\"})\n\n_RetType = TypeVar(\"_RetType\")\n_CharsetResolver = Callable[[ClientResponse, bytes], str]\n\n\n@final\nclass ClientSession:\n    \"\"\"First-class interface for making HTTP requests.\"\"\"\n\n    __slots__ = (\n        \"_base_url\",\n        \"_source_traceback\",\n        \"_connector\",\n        \"_loop\",\n        \"_cookie_jar\",\n        \"_connector_owner\",\n        \"_default_auth\",\n        \"_version\",\n        \"_json_serialize\",\n        \"_requote_redirect_url\",\n        \"_timeout\",\n        \"_raise_for_status\",\n        \"_auto_decompress\",\n        \"_trust_env\",\n        \"_default_headers\",\n        \"_skip_auto_headers\",\n        \"_request_class\",\n        \"_response_class\",\n        \"_ws_response_class\",\n        \"_trace_configs\",\n        \"_read_bufsize\",\n        \"_max_line_size\",\n        \"_max_field_size\",\n        \"_resolve_charset\",\n    )\n\n    def __init__(\n        self,\n        base_url: Optional[StrOrURL] = None,\n        *,\n        connector: Optional[BaseConnector] = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        json_serialize: JSONEncoder = json.dumps,\n        request_class: Type[ClientRequest] = ClientRequest,\n        response_class: Type[ClientResponse] = ClientResponse,\n        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,\n        version: HttpVersion = http.HttpVersion11,\n        cookie_jar: Optional[AbstractCookieJar] = None,\n        connector_owner: bool = True,\n        raise_for_status: Union[\n            bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = False,\n        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,\n        auto_decompress: bool = True,\n        trust_env: bool = False,\n        requote_redirect_url: bool = True,\n        trace_configs: Optional[List[TraceConfig[object]]] = None,\n        read_bufsize: int = 2**16,\n        max_line_size: int = 8190,\n        max_field_size: int = 8190,\n        fallback_charset_resolver: _CharsetResolver = lambda r, b: \"utf-8\",\n    ) -> None:\n        # We initialise _connector to None immediately, as it's referenced in __del__()\n        # and could cause issues if an exception occurs during initialisation.\n        self._connector: Optional[BaseConnector] = None\n        if base_url is None or isinstance(base_url, URL):\n            self._base_url: Optional[URL] = base_url\n        else:\n            self._base_url = URL(base_url)\n            assert (\n                self._base_url.origin() == self._base_url\n            ), \"Only absolute URLs without path part are supported\"\n\n        loop = asyncio.get_running_loop()\n\n        if timeout is sentinel or timeout is None:\n            timeout = DEFAULT_TIMEOUT\n        if not isinstance(timeout, ClientTimeout):\n            raise ValueError(\n                f\"timeout parameter cannot be of {type(timeout)} type, \"\n                \"please use 'timeout=ClientTimeout(...)'\",\n            )\n        self._timeout = timeout\n\n        if connector is None:\n            connector = TCPConnector()\n        # Initialize these three attrs before raising any exception,\n        # they are used in __del__\n        self._connector = connector\n        self._loop = loop\n        if loop.get_debug():\n            self._source_traceback: Optional[traceback.StackSummary] = (\n                traceback.extract_stack(sys._getframe(1))\n            )\n        else:\n            self._source_traceback = None\n\n        if connector._loop is not loop:\n            raise RuntimeError(\"Session and connector have to use same event loop\")\n\n        if cookie_jar is None:\n            cookie_jar = CookieJar()\n        self._cookie_jar = cookie_jar\n\n        if cookies is not None:\n            self._cookie_jar.update_cookies(cookies)\n\n        self._connector_owner = connector_owner\n        self._default_auth = auth\n        self._version = version\n        self._json_serialize = json_serialize\n        self._raise_for_status = raise_for_status\n        self._auto_decompress = auto_decompress\n        self._trust_env = trust_env\n        self._requote_redirect_url = requote_redirect_url\n        self._read_bufsize = read_bufsize\n        self._max_line_size = max_line_size\n        self._max_field_size = max_field_size\n\n        # Convert to list of tuples\n        if headers:\n            real_headers: CIMultiDict[str] = CIMultiDict(headers)\n        else:\n            real_headers = CIMultiDict()\n        self._default_headers: CIMultiDict[str] = real_headers\n        if skip_auto_headers is not None:\n            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)\n        else:\n            self._skip_auto_headers = frozenset()\n\n        self._request_class = request_class\n        self._response_class = response_class\n        self._ws_response_class = ws_response_class\n\n        self._trace_configs = trace_configs or []\n        for trace_config in self._trace_configs:\n            trace_config.freeze()\n\n        self._resolve_charset = fallback_charset_resolver\n\n    def __init_subclass__(cls: Type[\"ClientSession\"]) -> None:\n        raise TypeError(\n            \"Inheritance class {} from ClientSession \"\n            \"is forbidden\".format(cls.__name__)\n        )\n\n    def __del__(self, _warnings: Any = warnings) -> None:\n        if not self.closed:\n            _warnings.warn(\n                f\"Unclosed client session {self!r}\",\n                ResourceWarning,\n                source=self,\n            )\n            context = {\"client_session\": self, \"message\": \"Unclosed client session\"}\n            if self._source_traceback is not None:\n                context[\"source_traceback\"] = self._source_traceback\n            self._loop.call_exception_handler(context)\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def request(\n            self,\n            method: str,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def request(\n            self, method: str, url: StrOrURL, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP request.\"\"\"\n            return _RequestContextManager(self._request(method, url, **kwargs))\n\n    def _build_url(self, str_or_url: StrOrURL) -> URL:\n        url = URL(str_or_url)\n        if self._base_url is None:\n            return url\n        else:\n            assert not url.is_absolute() and url.path.startswith(\"/\")\n            return self._base_url.join(url)\n\n    async def _request(\n        self,\n        method: str,\n        str_or_url: StrOrURL,\n        *,\n        params: Optional[Mapping[str, str]] = None,\n        data: Any = None,\n        json: Any = None,\n        cookies: Optional[LooseCookies] = None,\n        headers: Optional[LooseHeaders] = None,\n        skip_auto_headers: Optional[Iterable[str]] = None,\n        auth: Optional[BasicAuth] = None,\n        allow_redirects: bool = True,\n        max_redirects: int = 10,\n        compress: Optional[str] = None,\n        chunked: Optional[bool] = None,\n        expect100: bool = False,\n        raise_for_status: Union[\n            None, bool, Callable[[ClientResponse], Awaitable[None]]\n        ] = None,\n        read_until_eof: bool = True,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        trace_request_ctx: Optional[Mapping[str, str]] = None,\n        read_bufsize: Optional[int] = None,\n        auto_decompress: Optional[bool] = None,\n        max_line_size: Optional[int] = None,\n        max_field_size: Optional[int] = None,\n    ) -> ClientResponse:\n        # NOTE: timeout clamps existing connect and read timeouts.  We cannot\n        # set the default to None because we need to detect if the user wants\n        # to use the existing timeouts by setting timeout to None.\n\n        if self.closed:\n            raise RuntimeError(\"Session is closed\")\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        if data is not None and json is not None:\n            raise ValueError(\n                \"data and json parameters can not be used at the same time\"\n            )\n        elif json is not None:\n            data = payload.JsonPayload(json, dumps=self._json_serialize)\n\n        redirects = 0\n        history = []\n        version = self._version\n        params = params or {}\n\n        # Merge with default headers and transform to CIMultiDict\n        headers = self._prepare_headers(headers)\n        proxy_headers = self._prepare_headers(proxy_headers)\n\n        try:\n            url = self._build_url(str_or_url)\n        except ValueError as e:\n            raise InvalidUrlClientError(str_or_url) from e\n\n        assert self._connector is not None\n        if url.scheme not in self._connector.allowed_protocol_schema_set:\n            raise NonHttpUrlClientError(url)\n\n        skip_headers = set(self._skip_auto_headers)\n        if skip_auto_headers is not None:\n            for i in skip_auto_headers:\n                skip_headers.add(istr(i))\n\n        if proxy is not None:\n            try:\n                proxy = URL(proxy)\n            except ValueError as e:\n                raise InvalidURL(proxy) from e\n\n        if timeout is sentinel or timeout is None:\n            real_timeout: ClientTimeout = self._timeout\n        else:\n            real_timeout = timeout\n        # timeout is cumulative for all request operations\n        # (request, redirects, responses, data consuming)\n        tm = TimeoutHandle(\n            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold\n        )\n        handle = tm.start()\n\n        if read_bufsize is None:\n            read_bufsize = self._read_bufsize\n\n        if auto_decompress is None:\n            auto_decompress = self._auto_decompress\n\n        if max_line_size is None:\n            max_line_size = self._max_line_size\n\n        if max_field_size is None:\n            max_field_size = self._max_field_size\n\n        traces = [\n            Trace(\n                self,\n                trace_config,\n                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),\n            )\n            for trace_config in self._trace_configs\n        ]\n\n        for trace in traces:\n            await trace.send_request_start(method, url.update_query(params), headers)\n\n        timer = tm.timer()\n        try:\n            with timer:\n                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests\n                retry_persistent_connection = method in IDEMPOTENT_METHODS\n                while True:\n                    url, auth_from_url = strip_auth_from_url(url)\n                    if not url.raw_host:\n                        # NOTE: Bail early, otherwise, causes `InvalidURL` through\n                        # NOTE: `self._request_class()` below.\n                        err_exc_cls = (\n                            InvalidUrlRedirectClientError\n                            if redirects\n                            else InvalidUrlClientError\n                        )\n                        raise err_exc_cls(url)\n                    if auth and auth_from_url:\n                        raise ValueError(\n                            \"Cannot combine AUTH argument with \"\n                            \"credentials encoded in URL\"\n                        )\n\n                    if auth is None:\n                        auth = auth_from_url\n                    if auth is None:\n                        auth = self._default_auth\n                    # It would be confusing if we support explicit\n                    # Authorization header with auth argument\n                    if auth is not None and hdrs.AUTHORIZATION in headers:\n                        raise ValueError(\n                            \"Cannot combine AUTHORIZATION header \"\n                            \"with AUTH argument or credentials \"\n                            \"encoded in URL\"\n                        )\n\n                    all_cookies = self._cookie_jar.filter_cookies(url)\n\n                    if cookies is not None:\n                        tmp_cookie_jar = CookieJar()\n                        tmp_cookie_jar.update_cookies(cookies)\n                        req_cookies = tmp_cookie_jar.filter_cookies(url)\n                        if req_cookies:\n                            all_cookies.load(req_cookies)\n\n                    if proxy is not None:\n                        proxy = URL(proxy)\n                    elif self._trust_env:\n                        with suppress(LookupError):\n                            proxy, proxy_auth = get_env_proxy_for_url(url)\n\n                    req = self._request_class(\n                        method,\n                        url,\n                        params=params,\n                        headers=headers,\n                        skip_auto_headers=skip_headers if skip_headers else None,\n                        data=data,\n                        cookies=all_cookies,\n                        auth=auth,\n                        version=version,\n                        compress=compress,\n                        chunked=chunked,\n                        expect100=expect100,\n                        loop=self._loop,\n                        response_class=self._response_class,\n                        proxy=proxy,\n                        proxy_auth=proxy_auth,\n                        timer=timer,\n                        session=self,\n                        ssl=ssl,\n                        server_hostname=server_hostname,\n                        proxy_headers=proxy_headers,\n                        traces=traces,\n                        trust_env=self.trust_env,\n                    )\n\n                    # connection timeout\n                    try:\n                        async with ceil_timeout(\n                            real_timeout.connect,\n                            ceil_threshold=real_timeout.ceil_threshold,\n                        ):\n                            conn = await self._connector.connect(\n                                req, traces=traces, timeout=real_timeout\n                            )\n                    except asyncio.TimeoutError as exc:\n                        raise ConnectionTimeoutError(\n                            f\"Connection timeout to host {url}\"\n                        ) from exc\n\n                    assert conn.transport is not None\n\n                    assert conn.protocol is not None\n                    conn.protocol.set_response_params(\n                        timer=timer,\n                        skip_payload=method_must_be_empty_body(method),\n                        read_until_eof=read_until_eof,\n                        auto_decompress=auto_decompress,\n                        read_timeout=real_timeout.sock_read,\n                        read_bufsize=read_bufsize,\n                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,\n                        max_line_size=max_line_size,\n                        max_field_size=max_field_size,\n                    )\n\n                    try:\n                        try:\n                            resp = await req.send(conn)\n                            try:\n                                await resp.start(conn)\n                            except BaseException:\n                                resp.close()\n                                raise\n                        except BaseException:\n                            conn.close()\n                            raise\n                    except (ClientOSError, ServerDisconnectedError):\n                        if retry_persistent_connection:\n                            retry_persistent_connection = False\n                            continue\n                        raise\n                    except ClientError:\n                        raise\n                    except OSError as exc:\n                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                            raise\n                        raise ClientOSError(*exc.args) from exc\n\n                    self._cookie_jar.update_cookies(resp.cookies, resp.url)\n\n                    # redirects\n                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:\n                        for trace in traces:\n                            await trace.send_request_redirect(\n                                method, url.update_query(params), headers, resp\n                            )\n\n                        redirects += 1\n                        history.append(resp)\n                        if max_redirects and redirects >= max_redirects:\n                            resp.close()\n                            raise TooManyRedirects(\n                                history[0].request_info, tuple(history)\n                            )\n\n                        # For 301 and 302, mimic IE, now changed in RFC\n                        # https://github.com/kennethreitz/requests/pull/269\n                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (\n                            resp.status in (301, 302) and resp.method == hdrs.METH_POST\n                        ):\n                            method = hdrs.METH_GET\n                            data = None\n                            if headers.get(hdrs.CONTENT_LENGTH):\n                                headers.pop(hdrs.CONTENT_LENGTH)\n\n                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(\n                            hdrs.URI\n                        )\n                        if r_url is None:\n                            # see github.com/aio-libs/aiohttp/issues/2022\n                            break\n                        else:\n                            # reading from correct redirection\n                            # response is forbidden\n                            resp.release()\n\n                        try:\n                            parsed_redirect_url = URL(\n                                r_url, encoded=not self._requote_redirect_url\n                            )\n                        except ValueError as e:\n                            raise InvalidUrlRedirectClientError(\n                                r_url,\n                                \"Server attempted redirecting to a location that does not look like a URL\",\n                            ) from e\n\n                        scheme = parsed_redirect_url.scheme\n                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:\n                            resp.close()\n                            raise NonHttpUrlRedirectClientError(r_url)\n                        elif not scheme:\n                            parsed_redirect_url = url.join(parsed_redirect_url)\n\n                        is_same_host_https_redirect = (\n                            url.host == parsed_redirect_url.host\n                            and parsed_redirect_url.scheme == \"https\"\n                            and url.scheme == \"http\"\n                        )\n\n                        try:\n                            redirect_origin = parsed_redirect_url.origin()\n                        except ValueError as origin_val_err:\n                            raise InvalidUrlRedirectClientError(\n                                parsed_redirect_url,\n                                \"Invalid redirect URL origin\",\n                            ) from origin_val_err\n\n                        if (\n                            url.origin() != redirect_origin\n                            and not is_same_host_https_redirect\n                        ):\n                            auth = None\n                            headers.pop(hdrs.AUTHORIZATION, None)\n\n                        url = parsed_redirect_url\n                        params = {}\n                        resp.release()\n                        continue\n\n                    break\n\n            # check response status\n            if raise_for_status is None:\n                raise_for_status = self._raise_for_status\n\n            if raise_for_status is None:\n                pass\n            elif callable(raise_for_status):\n                await raise_for_status(resp)\n            elif raise_for_status:\n                resp.raise_for_status()\n\n            # register connection\n            if handle is not None:\n                if resp.connection is not None:\n                    resp.connection.add_callback(handle.cancel)\n                else:\n                    handle.cancel()\n\n            resp._history = tuple(history)\n\n            for trace in traces:\n                await trace.send_request_end(\n                    method, url.update_query(params), headers, resp\n                )\n            return resp\n\n        except BaseException as e:\n            # cleanup timer\n            tm.close()\n            if handle:\n                handle.cancel()\n                handle = None\n\n            for trace in traces:\n                await trace.send_request_exception(\n                    method, url.update_query(params), headers, e\n                )\n            raise\n\n    def ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> \"_WSRequestContextManager\":\n        \"\"\"Initiate websocket connection.\"\"\"\n        return _WSRequestContextManager(\n            self._ws_connect(\n                url,\n                method=method,\n                protocols=protocols,\n                timeout=timeout,\n                receive_timeout=receive_timeout,\n                autoclose=autoclose,\n                autoping=autoping,\n                heartbeat=heartbeat,\n                auth=auth,\n                origin=origin,\n                params=params,\n                headers=headers,\n                proxy=proxy,\n                proxy_auth=proxy_auth,\n                ssl=ssl,\n                server_hostname=server_hostname,\n                proxy_headers=proxy_headers,\n                compress=compress,\n                max_msg_size=max_msg_size,\n            )\n        )\n\n    async def _ws_connect(\n        self,\n        url: StrOrURL,\n        *,\n        method: str = hdrs.METH_GET,\n        protocols: Collection[str] = (),\n        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,\n        receive_timeout: Optional[float] = None,\n        autoclose: bool = True,\n        autoping: bool = True,\n        heartbeat: Optional[float] = None,\n        auth: Optional[BasicAuth] = None,\n        origin: Optional[str] = None,\n        params: Optional[Mapping[str, str]] = None,\n        headers: Optional[LooseHeaders] = None,\n        proxy: Optional[StrOrURL] = None,\n        proxy_auth: Optional[BasicAuth] = None,\n        ssl: Union[SSLContext, bool, Fingerprint] = True,\n        server_hostname: Optional[str] = None,\n        proxy_headers: Optional[LooseHeaders] = None,\n        compress: int = 0,\n        max_msg_size: int = 4 * 1024 * 1024,\n    ) -> ClientWebSocketResponse:\n        if timeout is sentinel or timeout is None:\n            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT\n        else:\n            if isinstance(timeout, ClientWSTimeout):\n                ws_timeout = timeout\n            else:\n                warnings.warn(\n                    \"parameter 'timeout' of type 'float' \"\n                    \"is deprecated, please use \"\n                    \"'timeout=ClientWSTimeout(ws_close=...)'\",\n                    DeprecationWarning,\n                    stacklevel=2,\n                )\n                ws_timeout = ClientWSTimeout(ws_close=timeout)\n\n        if receive_timeout is not None:\n            warnings.warn(\n                \"float parameter 'receive_timeout' \"\n                \"is deprecated, please use parameter \"\n                \"'timeout=ClientWSTimeout(ws_receive=...)'\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)\n\n        if headers is None:\n            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        default_headers = {\n            hdrs.UPGRADE: \"websocket\",\n            hdrs.CONNECTION: \"Upgrade\",\n            hdrs.SEC_WEBSOCKET_VERSION: \"13\",\n        }\n\n        for key, value in default_headers.items():\n            real_headers.setdefault(key, value)\n\n        sec_key = base64.b64encode(os.urandom(16))\n        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()\n\n        if protocols:\n            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = \",\".join(protocols)\n        if origin is not None:\n            real_headers[hdrs.ORIGIN] = origin\n        if compress:\n            extstr = ws_ext_gen(compress=compress)\n            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                \"got {!r} instead.\".format(ssl)\n            )\n\n        # send request\n        resp = await self.request(\n            method,\n            url,\n            params=params,\n            headers=real_headers,\n            read_until_eof=False,\n            auth=auth,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            ssl=ssl,\n            server_hostname=server_hostname,\n            proxy_headers=proxy_headers,\n        )\n\n        try:\n            # check handshake\n            if resp.status != 101:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid response status\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.UPGRADE, \"\").lower() != \"websocket\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid upgrade header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            if resp.headers.get(hdrs.CONNECTION, \"\").lower() != \"upgrade\":\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid connection header\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # key calculation\n            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, \"\")\n            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()\n            if r_key != match:\n                raise WSServerHandshakeError(\n                    resp.request_info,\n                    resp.history,\n                    message=\"Invalid challenge response\",\n                    status=resp.status,\n                    headers=resp.headers,\n                )\n\n            # websocket protocol\n            protocol = None\n            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:\n                resp_protocols = [\n                    proto.strip()\n                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(\",\")\n                ]\n\n                for proto in resp_protocols:\n                    if proto in protocols:\n                        protocol = proto\n                        break\n\n            # websocket compress\n            notakeover = False\n            if compress:\n                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)\n                if compress_hdrs:\n                    try:\n                        compress, notakeover = ws_ext_parse(compress_hdrs)\n                    except WSHandshakeError as exc:\n                        raise WSServerHandshakeError(\n                            resp.request_info,\n                            resp.history,\n                            message=exc.args[0],\n                            status=resp.status,\n                            headers=resp.headers,\n                        ) from exc\n                else:\n                    compress = 0\n                    notakeover = False\n\n            conn = resp.connection\n            assert conn is not None\n            conn_proto = conn.protocol\n            assert conn_proto is not None\n\n            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater\n            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible\n            if ws_timeout.ws_receive is None:\n                # Reset regardless\n                conn_proto.read_timeout = None\n            elif conn_proto.read_timeout is not None:\n                conn_proto.read_timeout = max(\n                    ws_timeout.ws_receive, conn_proto.read_timeout\n                )\n\n            transport = conn.transport\n            assert transport is not None\n            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(\n                conn_proto, 2**16, loop=self._loop\n            )\n            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)\n            writer = WebSocketWriter(\n                conn_proto,\n                transport,\n                use_mask=True,\n                compress=compress,\n                notakeover=notakeover,\n            )\n        except BaseException:\n            resp.close()\n            raise\n        else:\n            return self._ws_response_class(\n                reader,\n                writer,\n                protocol,\n                resp,\n                ws_timeout,\n                autoclose,\n                autoping,\n                self._loop,\n                heartbeat=heartbeat,\n                compress=compress,\n                client_notakeover=notakeover,\n            )\n\n    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> \"CIMultiDict[str]\":\n        \"\"\"Add default headers and transform it to CIMultiDict\"\"\"\n        # Convert headers to MultiDict\n        result = CIMultiDict(self._default_headers)\n        if headers:\n            if not isinstance(headers, (MultiDictProxy, MultiDict)):\n                headers = CIMultiDict(headers)\n            added_names: Set[str] = set()\n            for key, value in headers.items():\n                if key in added_names:\n                    result.add(key, value)\n                else:\n                    result[key] = value\n                    added_names.add(key)\n        return result\n\n    if sys.version_info >= (3, 11) and TYPE_CHECKING:\n\n        def get(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def options(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def head(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def post(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def put(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def patch(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n        def delete(\n            self,\n            url: StrOrURL,\n            **kwargs: Unpack[_RequestOptions],\n        ) -> \"_RequestContextManager\": ...\n\n    else:\n\n        def get(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP GET request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def options(\n            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP OPTIONS request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def head(\n            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP HEAD request.\"\"\"\n            return _RequestContextManager(\n                self._request(\n                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs\n                )\n            )\n\n        def post(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP POST request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_POST, url, data=data, **kwargs)\n            )\n\n        def put(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PUT request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PUT, url, data=data, **kwargs)\n            )\n\n        def patch(\n            self, url: StrOrURL, *, data: Any = None, **kwargs: Any\n        ) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP PATCH request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)\n            )\n\n        def delete(self, url: StrOrURL, **kwargs: Any) -> \"_RequestContextManager\":\n            \"\"\"Perform HTTP DELETE request.\"\"\"\n            return _RequestContextManager(\n                self._request(hdrs.METH_DELETE, url, **kwargs)\n            )\n\n    async def close(self) -> None:\n        \"\"\"Close underlying connector.\n\n        Release all acquired resources.\n        \"\"\"\n        if not self.closed:\n            if self._connector is not None and self._connector_owner:\n                await self._connector.close()\n            self._connector = None\n\n    @property\n    def closed(self) -> bool:\n        \"\"\"Is client session closed.\n\n        A readonly property.\n        \"\"\"\n        return self._connector is None or self._connector.closed\n\n    @property\n    def connector(self) -> Optional[BaseConnector]:\n        \"\"\"Connector instance used for the session.\"\"\"\n        return self._connector\n\n    @property\n    def cookie_jar(self) -> AbstractCookieJar:\n        \"\"\"The session cookies.\"\"\"\n        return self._cookie_jar\n\n    @property\n    def version(self) -> Tuple[int, int]:\n        \"\"\"The session HTTP protocol version.\"\"\"\n        return self._version\n\n    @property\n    def requote_redirect_url(self) -> bool:\n        \"\"\"Do URL requoting on redirection handling.\"\"\"\n        return self._requote_redirect_url\n\n    @property\n    def timeout(self) -> ClientTimeout:\n        \"\"\"Timeout for the session.\"\"\"\n        return self._timeout\n\n    @property\n    def headers(self) -> \"CIMultiDict[str]\":\n        \"\"\"The default headers of the client session.\"\"\"\n        return self._default_headers\n\n    @property\n    def skip_auto_headers(self) -> FrozenSet[istr]:\n        \"\"\"Headers for which autogeneration should be skipped\"\"\"\n        return self._skip_auto_headers\n\n    @property\n    def auth(self) -> Optional[BasicAuth]:\n        \"\"\"An object that represents HTTP Basic Authorization\"\"\"\n        return self._default_auth\n\n    @property\n    def json_serialize(self) -> JSONEncoder:\n        \"\"\"Json serializer callable\"\"\"\n        return self._json_serialize\n\n    @property\n    def connector_owner(self) -> bool:\n        \"\"\"Should connector be closed on session closing\"\"\"\n        return self._connector_owner\n\n    @property\n    def raise_for_status(\n        self,\n    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:\n        \"\"\"Should `ClientResponse.raise_for_status()` be called for each response.\"\"\"\n        return self._raise_for_status\n\n    @property\n    def auto_decompress(self) -> bool:\n        \"\"\"Should the body response be automatically decompressed.\"\"\"\n        return self._auto_decompress\n\n    @property\n    def trust_env(self) -> bool:\n        \"\"\"\n        Should proxies information from environment or netrc be trusted.\n\n        Information is from HTTP_PROXY / HTTPS_PROXY environment variables\n        or ~/.netrc file if present.\n        \"\"\"\n        return self._trust_env\n\n    @property\n    def trace_configs(self) -> List[TraceConfig[Any]]:\n        \"\"\"A list of TraceConfig instances used for client tracing\"\"\"\n        return self._trace_configs\n\n    def detach(self) -> None:\n        \"\"\"Detach connector from session without closing the former.\n\n        Session is switched to closed state anyway.\n        \"\"\"\n        self._connector = None\n\n    async def __aenter__(self) -> \"ClientSession\":\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        await self.close()\n\n\nclass _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]):\n    __slots__ = (\"_coro\", \"_resp\")\n\n    def __init__(self, coro: Coroutine[\"asyncio.Future[Any]\", None, _RetType]) -> None:\n        self._coro = coro\n\n    def send(self, arg: None) -> \"asyncio.Future[Any]\":\n        return self._coro.send(arg)\n\n    def throw(self, *args: Any, **kwargs: Any) -> \"asyncio.Future[Any]\":\n        return self._coro.throw(*args, **kwargs)\n\n    def close(self) -> None:\n        return self._coro.close()\n\n    def __await__(self) -> Generator[Any, None, _RetType]:\n        ret = self._coro.__await__()\n        return ret\n\n    def __iter__(self) -> Generator[Any, None, _RetType]:\n        return self.__await__()\n\n    async def __aenter__(self) -> _RetType:\n        self._resp = await self._coro\n        return self._resp\n\n\nclass _RequestContextManager(_BaseRequestContextManager[ClientResponse]):\n    __slots__ = ()\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        # We're basing behavior on the exception as it can be caused by\n        # user code unrelated to the status of the connection.  If you\n        # would like to close a connection you must do that\n        # explicitly.  Otherwise connection error handling should kick in\n        # and close/recycle the connection as required.\n        self._resp.release()\n        await self._resp.wait_for_close()\n\n\nclass _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]):\n    __slots__ = ()\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        await self._resp.close()\n\n\nclass _SessionRequestContextManager:\n    __slots__ = (\"_coro\", \"_resp\", \"_session\")\n\n    def __init__(\n        self,\n        coro: Coroutine[\"asyncio.Future[Any]\", None, ClientResponse],\n        session: ClientSession,\n    ) -> None:\n        self._coro = coro\n        self._resp: Optional[ClientResponse] = None\n        self._session = session\n\n    async def __aenter__(self) -> ClientResponse:\n        try:\n            self._resp = await self._coro\n        except BaseException:\n            await self._session.close()\n            raise\n        else:\n            return self._resp\n\n    async def __aexit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc: Optional[BaseException],\n        tb: Optional[TracebackType],\n    ) -> None:\n        assert self._resp is not None\n        self._resp.close()\n        await self._session.close()\n\n\ndef request(\n    method: str,\n    url: StrOrURL,\n    *,\n    params: Optional[Mapping[str, str]] = None,\n    data: Any = None,\n    json: Any = None,\n    headers: Optional[LooseHeaders] = None,\n    skip_auto_headers: Optional[Iterable[str]] = None,\n    auth: Optional[BasicAuth] = None,\n    allow_redirects: bool = True,\n    max_redirects: int = 10,\n    compress: Optional[str] = None,\n    chunked: Optional[bool] = None,\n    expect100: bool = False,\n    raise_for_status: Optional[bool] = None,\n    read_until_eof: bool = True,\n    proxy: Optional[StrOrURL] = None,\n    proxy_auth: Optional[BasicAuth] = None,\n    timeout: Union[ClientTimeout, _SENTINEL] = sentinel,\n    cookies: Optional[LooseCookies] = None,\n    version: HttpVersion = http.HttpVersion11,\n    connector: Optional[BaseConnector] = None,\n    read_bufsize: Optional[int] = None,\n    max_line_size: int = 8190,\n    max_field_size: int = 8190,\n) -> _SessionRequestContextManager:\n    \"\"\"Constructs and sends a request.\n\n    Returns response object.\n    method - HTTP method\n    url - request url\n    params - (optional) Dictionary or bytes to be sent in the query\n      string of the new request\n    data - (optional) Dictionary, bytes, or file-like object to\n      send in the body of the request\n    json - (optional) Any json compatible python object\n    headers - (optional) Dictionary of HTTP Headers to send with\n      the request\n    cookies - (optional) Dict object to send with the request\n    auth - (optional) BasicAuth named tuple represent HTTP Basic Auth\n    auth - aiohttp.helpers.BasicAuth\n    allow_redirects - (optional) If set to False, do not follow\n      redirects\n    version - Request HTTP version.\n    compress - Set to True if request has to be compressed\n       with deflate encoding.\n    chunked - Set to chunk size for chunked transfer encoding.\n    expect100 - Expect 100-continue response from server.\n    connector - BaseConnector sub-class instance to support\n       connection pooling.\n    read_until_eof - Read response until eof if response\n       does not have Content-Length header.\n    loop - Optional event loop.\n    timeout - Optional ClientTimeout settings structure, 5min\n       total timeout by default.\n    Usage::\n      >>> import aiohttp\n      >>> async with aiohttp.request('GET', 'http://python.org/') as resp:\n      ...    print(resp)\n      ...    data = await resp.read()\n      <ClientResponse(https://www.python.org/) [200 OK]>\n    \"\"\"\n    connector_owner = False\n    if connector is None:\n        connector_owner = True\n        connector = TCPConnector(force_close=True)\n\n    session = ClientSession(\n        cookies=cookies,\n        version=version,\n        timeout=timeout,\n        connector=connector,\n        connector_owner=connector_owner,\n    )\n\n    return _SessionRequestContextManager(\n        session._request(\n            method,\n            url,\n            params=params,\n            data=data,\n            json=json,\n            headers=headers,\n            skip_auto_headers=skip_auto_headers,\n            auth=auth,\n            allow_redirects=allow_redirects,\n            max_redirects=max_redirects,\n            compress=compress,\n            chunked=chunked,\n            expect100=expect100,\n            raise_for_status=raise_for_status,\n            read_until_eof=read_until_eof,\n            proxy=proxy,\n            proxy_auth=proxy_auth,\n            read_bufsize=read_bufsize,\n            max_line_size=max_line_size,\n            max_field_size=max_field_size,\n        ),\n        session,\n    )\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Authorization Header Not Dropped on Redirect to Different Origin with Base URL Set

**Description:**
When a client session is configured with a base URL and global authentication, the `Authorization` header is not removed when a redirect leads to a different origin. This can result in unintended exposure of credentials to external hosts.

**Example Code:**
```python
import aiohttp
from aiohttp import web

async def handle_initial_request(request):
    # This handler redirects to a different host
    raise web.HTTPFound('http://host2.com/path2')

async def handle_redirected_request(request):
    # This handler expects the Authorization header to be absent
    if 'Authorization' in request.headers:
        raise web.HTTPInternalServerError()

async def main():
    # Setup server for host1.com
    app1 = web.Application()
    app1.router.add_get('/path1', handle_initial_request)
    runner1 = web.AppRunner(app1)
    await runner1.setup()
    site1 = web.TCPSite(runner1, 'host1.com', 8080)
    await site1.start()

    # Setup server for host2.com
    app2 = web.Application()
    app2.router.add_get('/path2', handle_redirected_request)
    runner2 = web.AppRunner(app2)
    await runner2.setup()
    site2 = web.TCPSite(runner2, 'host2.com', 8081)
    await site2.start()

    connector = aiohttp.TCPConnector()
    async with aiohttp.ClientSession(
        connector=connector,
        base_url='http://host1.com:8080',
        auth=aiohttp.BasicAuth('user', 'pass')
    ) as session:
        await session.get('/path1')  # This should drop the Authorization header on redirect

**Expected Behavior:**
When the client session follows a redirect to a different origin (`host2.com`), the `Authorization` header should be removed to prevent credential leakage. The redirected request to `http://host2.com/path2` should not include the `Authorization` header.

**Actual Behavior:**
The `Authorization` header is retained during the redirect, causing the assertion in the redirected request handler to fail and resulting in a `500 Internal Server Error`. This exposes sensitive authentication information to an unintended external host.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### aiohttp/client.py
"""HTTP Client for asyncio."""

import asyncio
import base64
import dataclasses
import hashlib
import json
import os
import sys
import traceback
import warnings
from contextlib import suppress
from types import TracebackType
from typing import (
    TYPE_CHECKING,
    Any,
    Awaitable,
    Callable,
    Collection,
    Coroutine,
    Final,
    FrozenSet,
    Generator,
    Generic,
    Iterable,
    List,
    Mapping,
    Optional,
    Set,
    Tuple,
    Type,
    TypedDict,
    TypeVar,
    Union,
    final,
)

from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr
from yarl import URL

from . import hdrs, http, payload
from .abc import AbstractCookieJar
from .client_exceptions import (
    ClientConnectionError,
    ClientConnectorCertificateError,
    ClientConnectorError,
    ClientConnectorSSLError,
    ClientError,
    ClientHttpProxyError,
    ClientOSError,
    ClientPayloadError,
    ClientProxyConnectionError,
    ClientResponseError,
    ClientSSLError,
    ConnectionTimeoutError,
    ContentTypeError,
    InvalidURL,
    InvalidUrlClientError,
    InvalidUrlRedirectClientError,
    NonHttpUrlClientError,
    NonHttpUrlRedirectClientError,
    RedirectClientError,
    ServerConnectionError,
    ServerDisconnectedError,
    ServerFingerprintMismatch,
    ServerTimeoutError,
    SocketTimeoutError,
    TooManyRedirects,
    WSServerHandshakeError,
)
from .client_reqrep import (
    SSL_ALLOWED_TYPES,
    ClientRequest,
    ClientResponse,
    Fingerprint,
    RequestInfo,
)
from .client_ws import (
    DEFAULT_WS_CLIENT_TIMEOUT,
    ClientWebSocketResponse,
    ClientWSTimeout,
)
from .connector import (
    HTTP_AND_EMPTY_SCHEMA_SET,
    BaseConnector,
    NamedPipeConnector,
    TCPConnector,
    UnixConnector,
)
from .cookiejar import CookieJar
from .helpers import (
    _SENTINEL,
    BasicAuth,
    TimeoutHandle,
    ceil_timeout,
    get_env_proxy_for_url,
    method_must_be_empty_body,
    sentinel,
    strip_auth_from_url,
)
from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter
from .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse
from .streams import FlowControlDataQueue
from .tracing import Trace, TraceConfig
from .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL

__all__ = (
    # client_exceptions
    "ClientConnectionError",
    "ClientConnectorCertificateError",
    "ClientConnectorError",
    "ClientConnectorSSLError",
    "ClientError",
    "ClientHttpProxyError",
    "ClientOSError",
    "ClientPayloadError",
    "ClientProxyConnectionError",
    "ClientResponseError",
    "ClientSSLError",
    "ConnectionTimeoutError",
    "ContentTypeError",
    "InvalidURL",
    "InvalidUrlClientError",
    "RedirectClientError",
    "NonHttpUrlClientError",
    "InvalidUrlRedirectClientError",
    "NonHttpUrlRedirectClientError",
    "ServerConnectionError",
    "ServerDisconnectedError",
    "ServerFingerprintMismatch",
    "ServerTimeoutError",
    "SocketTimeoutError",
    "TooManyRedirects",
    "WSServerHandshakeError",
    # client_reqrep
    "ClientRequest",
    "ClientResponse",
    "Fingerprint",
    "RequestInfo",
    # connector
    "BaseConnector",
    "TCPConnector",
    "UnixConnector",
    "NamedPipeConnector",
    # client_ws
    "ClientWebSocketResponse",
    # client
    "ClientSession",
    "ClientTimeout",
    "ClientWSTimeout",
    "request",
)


if TYPE_CHECKING:
    from ssl import SSLContext
else:
    SSLContext = None

if sys.version_info >= (3, 11) and TYPE_CHECKING:
    from typing import Unpack


class _RequestOptions(TypedDict, total=False):
    params: Union[Mapping[str, Union[str, int]], str, None]
    data: Any
    json: Any
    cookies: Union[LooseCookies, None]
    headers: Union[LooseHeaders, None]
    skip_auto_headers: Union[Iterable[str], None]
    auth: Union[BasicAuth, None]
    allow_redirects: bool
    max_redirects: int
    compress: Union[str, None]
    chunked: Union[bool, None]
    expect100: bool
    raise_for_status: Union[None, bool, Callable[[ClientResponse], Awaitable[None]]]
    read_until_eof: bool
    proxy: Union[StrOrURL, None]
    proxy_auth: Union[BasicAuth, None]
    timeout: "Union[ClientTimeout, _SENTINEL, None]"
    ssl: Union[SSLContext, bool, Fingerprint]
    server_hostname: Union[str, None]
    proxy_headers: Union[LooseHeaders, None]
    trace_request_ctx: Union[Mapping[str, str], None]
    read_bufsize: Union[int, None]
    auto_decompress: Union[bool, None]
    max_line_size: Union[int, None]
    max_field_size: Union[int, None]


@dataclasses.dataclass(frozen=True)
class ClientTimeout:
    total: Optional[float] = None
    connect: Optional[float] = None
    sock_read: Optional[float] = None
    sock_connect: Optional[float] = None
    ceil_threshold: float = 5

    # pool_queue_timeout: Optional[float] = None
    # dns_resolution_timeout: Optional[float] = None
    # socket_connect_timeout: Optional[float] = None
    # connection_acquiring_timeout: Optional[float] = None
    # new_connection_timeout: Optional[float] = None
    # http_header_timeout: Optional[float] = None
    # response_body_timeout: Optional[float] = None

    # to create a timeout specific for a single request, either
    # - create a completely new one to overwrite the default
    # - or use https://docs.python.org/3/library/dataclasses.html#dataclasses.replace
    # to overwrite the defaults


# 5 Minute default read timeout
DEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60)

# https://www.rfc-editor.org/rfc/rfc9110#section-9.2.2
IDEMPOTENT_METHODS = frozenset({"GET", "HEAD", "OPTIONS", "TRACE", "PUT", "DELETE"})

_RetType = TypeVar("_RetType")
_CharsetResolver = Callable[[ClientResponse, bytes], str]


@final
class ClientSession:
    """First-class interface for making HTTP requests."""

    __slots__ = (
        "_base_url",
        "_source_traceback",
        "_connector",
        "_loop",
        "_cookie_jar",
        "_connector_owner",
        "_default_auth",
        "_version",
        "_json_serialize",
        "_requote_redirect_url",
        "_timeout",
        "_raise_for_status",
        "_auto_decompress",
        "_trust_env",
        "_default_headers",
        "_skip_auto_headers",
        "_request_class",
        "_response_class",
        "_ws_response_class",
        "_trace_configs",
        "_read_bufsize",
        "_max_line_size",
        "_max_field_size",
        "_resolve_charset",
    )

    def __init__(
        self,
        base_url: Optional[StrOrURL] = None,
        *,
        connector: Optional[BaseConnector] = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        json_serialize: JSONEncoder = json.dumps,
        request_class: Type[ClientRequest] = ClientRequest,
        response_class: Type[ClientResponse] = ClientResponse,
        ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,
        version: HttpVersion = http.HttpVersion11,
        cookie_jar: Optional[AbstractCookieJar] = None,
        connector_owner: bool = True,
        raise_for_status: Union[
            bool, Callable[[ClientResponse], Awaitable[None]]
        ] = False,
        timeout: Union[_SENTINEL, ClientTimeout, None] = sentinel,
        auto_decompress: bool = True,
        trust_env: bool = False,
        requote_redirect_url: bool = True,
        trace_configs: Optional[List[TraceConfig[object]]] = None,
        read_bufsize: int = 2**16,
        max_line_size: int = 8190,
        max_field_size: int = 8190,
        fallback_charset_resolver: _CharsetResolver = lambda r, b: "utf-8",
    ) -> None:
        # We initialise _connector to None immediately, as it's referenced in __del__()
        # and could cause issues if an exception occurs during initialisation.
        self._connector: Optional[BaseConnector] = None
        if base_url is None or isinstance(base_url, URL):
            self._base_url: Optional[URL] = base_url
        else:
            self._base_url = URL(base_url)
            assert (
                self._base_url.origin() == self._base_url
            ), "Only absolute URLs without path part are supported"

        loop = asyncio.get_running_loop()

        if timeout is sentinel or timeout is None:
            timeout = DEFAULT_TIMEOUT
        if not isinstance(timeout, ClientTimeout):
            raise ValueError(
                f"timeout parameter cannot be of {type(timeout)} type, "
                "please use 'timeout=ClientTimeout(...)'",
            )
        self._timeout = timeout

        if connector is None:
            connector = TCPConnector()
        # Initialize these three attrs before raising any exception,
        # they are used in __del__
        self._connector = connector
        self._loop = loop
        if loop.get_debug():
            self._source_traceback: Optional[traceback.StackSummary] = (
                traceback.extract_stack(sys._getframe(1))
            )
        else:
            self._source_traceback = None

        if connector._loop is not loop:
            raise RuntimeError("Session and connector have to use same event loop")

        if cookie_jar is None:
            cookie_jar = CookieJar()
        self._cookie_jar = cookie_jar

        if cookies is not None:
            self._cookie_jar.update_cookies(cookies)

        self._connector_owner = connector_owner
        self._default_auth = auth
        self._version = version
        self._json_serialize = json_serialize
        self._raise_for_status = raise_for_status
        self._auto_decompress = auto_decompress
        self._trust_env = trust_env
        self._requote_redirect_url = requote_redirect_url
        self._read_bufsize = read_bufsize
        self._max_line_size = max_line_size
        self._max_field_size = max_field_size

        # Convert to list of tuples
        if headers:
            real_headers: CIMultiDict[str] = CIMultiDict(headers)
        else:
            real_headers = CIMultiDict()
        self._default_headers: CIMultiDict[str] = real_headers
        if skip_auto_headers is not None:
            self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)
        else:
            self._skip_auto_headers = frozenset()

        self._request_class = request_class
        self._response_class = response_class
        self._ws_response_class = ws_response_class

        self._trace_configs = trace_configs or []
        for trace_config in self._trace_configs:
            trace_config.freeze()

        self._resolve_charset = fallback_charset_resolver

    def __init_subclass__(cls: Type["ClientSession"]) -> None:
        raise TypeError(
            "Inheritance class {} from ClientSession "
            "is forbidden".format(cls.__name__)
        )

    def __del__(self, _warnings: Any = warnings) -> None:
        if not self.closed:
            _warnings.warn(
                f"Unclosed client session {self!r}",
                ResourceWarning,
                source=self,
            )
            context = {"client_session": self, "message": "Unclosed client session"}
            if self._source_traceback is not None:
                context["source_traceback"] = self._source_traceback
            self._loop.call_exception_handler(context)

    if sys.version_info >= (3, 11) and TYPE_CHECKING:

        def request(
            self,
            method: str,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

    else:

        def request(
            self, method: str, url: StrOrURL, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP request."""
            return _RequestContextManager(self._request(method, url, **kwargs))

    def _build_url(self, str_or_url: StrOrURL) -> URL:
        url = URL(str_or_url)
        if self._base_url is None:
            return url
        else:
            assert not url.is_absolute() and url.path.startswith("/")
            return self._base_url.join(url)

    async def _request(
        self,
        method: str,
        str_or_url: StrOrURL,
        *,
        params: Optional[Mapping[str, str]] = None,
        data: Any = None,
        json: Any = None,
        cookies: Optional[LooseCookies] = None,
        headers: Optional[LooseHeaders] = None,
        skip_auto_headers: Optional[Iterable[str]] = None,
        auth: Optional[BasicAuth] = None,
        allow_redirects: bool = True,
        max_redirects: int = 10,
        compress: Optional[str] = None,
        chunked: Optional[bool] = None,
        expect100: bool = False,
        raise_for_status: Union[
            None, bool, Callable[[ClientResponse], Awaitable[None]]
        ] = None,
        read_until_eof: bool = True,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        timeout: Union[ClientTimeout, _SENTINEL, None] = sentinel,
        ssl: Union[SSLContext, bool, Fingerprint] = True,
        server_hostname: Optional[str] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        trace_request_ctx: Optional[Mapping[str, str]] = None,
        read_bufsize: Optional[int] = None,
        auto_decompress: Optional[bool] = None,
        max_line_size: Optional[int] = None,
        max_field_size: Optional[int] = None,
    ) -> ClientResponse:
        # NOTE: timeout clamps existing connect and read timeouts.  We cannot
        # set the default to None because we need to detect if the user wants
        # to use the existing timeouts by setting timeout to None.

        if self.closed:
            raise RuntimeError("Session is closed")

        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, Fingerprint, or bool, "
                "got {!r} instead.".format(ssl)
            )

        if data is not None and json is not None:
            raise ValueError(
                "data and json parameters can not be used at the same time"
            )
        elif json is not None:
            data = payload.JsonPayload(json, dumps=self._json_serialize)

        redirects = 0
        history = []
        version = self._version
        params = params or {}

        # Merge with default headers and transform to CIMultiDict
        headers = self._prepare_headers(headers)
        proxy_headers = self._prepare_headers(proxy_headers)

        try:
            url = self._build_url(str_or_url)
        except ValueError as e:
            raise InvalidUrlClientError(str_or_url) from e

        assert self._connector is not None
        if url.scheme not in self._connector.allowed_protocol_schema_set:
            raise NonHttpUrlClientError(url)

        skip_headers = set(self._skip_auto_headers)
        if skip_auto_headers is not None:
            for i in skip_auto_headers:
                skip_headers.add(istr(i))

        if proxy is not None:
            try:
                proxy = URL(proxy)
            except ValueError as e:
                raise InvalidURL(proxy) from e

        if timeout is sentinel or timeout is None:
            real_timeout: ClientTimeout = self._timeout
        else:
            real_timeout = timeout
        # timeout is cumulative for all request operations
        # (request, redirects, responses, data consuming)
        tm = TimeoutHandle(
            self._loop, real_timeout.total, ceil_threshold=real_timeout.ceil_threshold
        )
        handle = tm.start()

        if read_bufsize is None:
            read_bufsize = self._read_bufsize

        if auto_decompress is None:
            auto_decompress = self._auto_decompress

        if max_line_size is None:
            max_line_size = self._max_line_size

        if max_field_size is None:
            max_field_size = self._max_field_size

        traces = [
            Trace(
                self,
                trace_config,
                trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
            )
            for trace_config in self._trace_configs
        ]

        for trace in traces:
            await trace.send_request_start(method, url.update_query(params), headers)

        timer = tm.timer()
        try:
            with timer:
                # https://www.rfc-editor.org/rfc/rfc9112.html#name-retrying-requests
                retry_persistent_connection = method in IDEMPOTENT_METHODS
                while True:
                    url, auth_from_url = strip_auth_from_url(url)
                    if not url.raw_host:
                        # NOTE: Bail early, otherwise, causes `InvalidURL` through
                        # NOTE: `self._request_class()` below.
                        err_exc_cls = (
                            InvalidUrlRedirectClientError
                            if redirects
                            else InvalidUrlClientError
                        )
                        raise err_exc_cls(url)
                    if auth and auth_from_url:
                        raise ValueError(
                            "Cannot combine AUTH argument with "
                            "credentials encoded in URL"
                        )

                    if auth is None:
                        auth = auth_from_url
                    if auth is None:
                        auth = self._default_auth
                    # It would be confusing if we support explicit
                    # Authorization header with auth argument
                    if auth is not None and hdrs.AUTHORIZATION in headers:
                        raise ValueError(
                            "Cannot combine AUTHORIZATION header "
                            "with AUTH argument or credentials "
                            "encoded in URL"
                        )

                    all_cookies = self._cookie_jar.filter_cookies(url)

                    if cookies is not None:
                        tmp_cookie_jar = CookieJar()
                        tmp_cookie_jar.update_cookies(cookies)
                        req_cookies = tmp_cookie_jar.filter_cookies(url)
                        if req_cookies:
                            all_cookies.load(req_cookies)

                    if proxy is not None:
                        proxy = URL(proxy)
                    elif self._trust_env:
                        with suppress(LookupError):
                            proxy, proxy_auth = get_env_proxy_for_url(url)

                    req = self._request_class(
                        method,
                        url,
                        params=params,
                        headers=headers,
                        skip_auto_headers=skip_headers if skip_headers else None,
                        data=data,
                        cookies=all_cookies,
                        auth=auth,
                        version=version,
                        compress=compress,
                        chunked=chunked,
                        expect100=expect100,
                        loop=self._loop,
                        response_class=self._response_class,
                        proxy=proxy,
                        proxy_auth=proxy_auth,
                        timer=timer,
                        session=self,
                        ssl=ssl,
                        server_hostname=server_hostname,
                        proxy_headers=proxy_headers,
                        traces=traces,
                        trust_env=self.trust_env,
                    )

                    # connection timeout
                    try:
                        async with ceil_timeout(
                            real_timeout.connect,
                            ceil_threshold=real_timeout.ceil_threshold,
                        ):
                            conn = await self._connector.connect(
                                req, traces=traces, timeout=real_timeout
                            )
                    except asyncio.TimeoutError as exc:
                        raise ConnectionTimeoutError(
                            f"Connection timeout to host {url}"
                        ) from exc

                    assert conn.transport is not None

                    assert conn.protocol is not None
                    conn.protocol.set_response_params(
                        timer=timer,
                        skip_payload=method_must_be_empty_body(method),
                        read_until_eof=read_until_eof,
                        auto_decompress=auto_decompress,
                        read_timeout=real_timeout.sock_read,
                        read_bufsize=read_bufsize,
                        timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
                        max_line_size=max_line_size,
                        max_field_size=max_field_size,
                    )

                    try:
                        try:
                            resp = await req.send(conn)
                            try:
                                await resp.start(conn)
                            except BaseException:
                                resp.close()
                                raise
                        except BaseException:
                            conn.close()
                            raise
                    except (ClientOSError, ServerDisconnectedError):
                        if retry_persistent_connection:
                            retry_persistent_connection = False
                            continue
                        raise
                    except ClientError:
                        raise
                    except OSError as exc:
                        if exc.errno is None and isinstance(exc, asyncio.TimeoutError):
                            raise
                        raise ClientOSError(*exc.args) from exc

                    self._cookie_jar.update_cookies(resp.cookies, resp.url)

                    # redirects
                    if resp.status in (301, 302, 303, 307, 308) and allow_redirects:
                        for trace in traces:
                            await trace.send_request_redirect(
                                method, url.update_query(params), headers, resp
                            )

                        redirects += 1
                        history.append(resp)
                        if max_redirects and redirects >= max_redirects:
                            resp.close()
                            raise TooManyRedirects(
                                history[0].request_info, tuple(history)
                            )

                        # For 301 and 302, mimic IE, now changed in RFC
                        # https://github.com/kennethreitz/requests/pull/269
                        if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (
                            resp.status in (301, 302) and resp.method == hdrs.METH_POST
                        ):
                            method = hdrs.METH_GET
                            data = None
                            if headers.get(hdrs.CONTENT_LENGTH):
                                headers.pop(hdrs.CONTENT_LENGTH)

                        r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(
                            hdrs.URI
                        )
                        if r_url is None:
                            # see github.com/aio-libs/aiohttp/issues/2022
                            break
                        else:
                            # reading from correct redirection
                            # response is forbidden
                            resp.release()

                        try:
                            parsed_redirect_url = URL(
                                r_url, encoded=not self._requote_redirect_url
                            )
                        except ValueError as e:
                            raise InvalidUrlRedirectClientError(
                                r_url,
                                "Server attempted redirecting to a location that does not look like a URL",
                            ) from e

                        scheme = parsed_redirect_url.scheme
                        if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:
                            resp.close()
                            raise NonHttpUrlRedirectClientError(r_url)
                        elif not scheme:
                            parsed_redirect_url = url.join(parsed_redirect_url)

                        is_same_host_https_redirect = (
                            url.host == parsed_redirect_url.host
                            and parsed_redirect_url.scheme == "https"
                            and url.scheme == "http"
                        )

                        try:
                            redirect_origin = parsed_redirect_url.origin()
                        except ValueError as origin_val_err:
                            raise InvalidUrlRedirectClientError(
                                parsed_redirect_url,
                                "Invalid redirect URL origin",
                            ) from origin_val_err

                        if (
                            url.origin() != redirect_origin
                            and not is_same_host_https_redirect
                        ):
                            auth = None
                            headers.pop(hdrs.AUTHORIZATION, None)

                        url = parsed_redirect_url
                        params = {}
                        resp.release()
                        continue

                    break

            # check response status
            if raise_for_status is None:
                raise_for_status = self._raise_for_status

            if raise_for_status is None:
                pass
            elif callable(raise_for_status):
                await raise_for_status(resp)
            elif raise_for_status:
                resp.raise_for_status()

            # register connection
            if handle is not None:
                if resp.connection is not None:
                    resp.connection.add_callback(handle.cancel)
                else:
                    handle.cancel()

            resp._history = tuple(history)

            for trace in traces:
                await trace.send_request_end(
                    method, url.update_query(params), headers, resp
                )
            return resp

        except BaseException as e:
            # cleanup timer
            tm.close()
            if handle:
                handle.cancel()
                handle = None

            for trace in traces:
                await trace.send_request_exception(
                    method, url.update_query(params), headers, e
                )
            raise

    def ws_connect(
        self,
        url: StrOrURL,
        *,
        method: str = hdrs.METH_GET,
        protocols: Collection[str] = (),
        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,
        receive_timeout: Optional[float] = None,
        autoclose: bool = True,
        autoping: bool = True,
        heartbeat: Optional[float] = None,
        auth: Optional[BasicAuth] = None,
        origin: Optional[str] = None,
        params: Optional[Mapping[str, str]] = None,
        headers: Optional[LooseHeaders] = None,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        ssl: Union[SSLContext, bool, Fingerprint] = True,
        server_hostname: Optional[str] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        compress: int = 0,
        max_msg_size: int = 4 * 1024 * 1024,
    ) -> "_WSRequestContextManager":
        """Initiate websocket connection."""
        return _WSRequestContextManager(
            self._ws_connect(
                url,
                method=method,
                protocols=protocols,
                timeout=timeout,
                receive_timeout=receive_timeout,
                autoclose=autoclose,
                autoping=autoping,
                heartbeat=heartbeat,
                auth=auth,
                origin=origin,
                params=params,
                headers=headers,
                proxy=proxy,
                proxy_auth=proxy_auth,
                ssl=ssl,
                server_hostname=server_hostname,
                proxy_headers=proxy_headers,
                compress=compress,
                max_msg_size=max_msg_size,
            )
        )

    async def _ws_connect(
        self,
        url: StrOrURL,
        *,
        method: str = hdrs.METH_GET,
        protocols: Collection[str] = (),
        timeout: Union[ClientWSTimeout, float, _SENTINEL, None] = sentinel,
        receive_timeout: Optional[float] = None,
        autoclose: bool = True,
        autoping: bool = True,
        heartbeat: Optional[float] = None,
        auth: Optional[BasicAuth] = None,
        origin: Optional[str] = None,
        params: Optional[Mapping[str, str]] = None,
        headers: Optional[LooseHeaders] = None,
        proxy: Optional[StrOrURL] = None,
        proxy_auth: Optional[BasicAuth] = None,
        ssl: Union[SSLContext, bool, Fingerprint] = True,
        server_hostname: Optional[str] = None,
        proxy_headers: Optional[LooseHeaders] = None,
        compress: int = 0,
        max_msg_size: int = 4 * 1024 * 1024,
    ) -> ClientWebSocketResponse:
        if timeout is sentinel or timeout is None:
            ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT
        else:
            if isinstance(timeout, ClientWSTimeout):
                ws_timeout = timeout
            else:
                warnings.warn(
                    "parameter 'timeout' of type 'float' "
                    "is deprecated, please use "
                    "'timeout=ClientWSTimeout(ws_close=...)'",
                    DeprecationWarning,
                    stacklevel=2,
                )
                ws_timeout = ClientWSTimeout(ws_close=timeout)

        if receive_timeout is not None:
            warnings.warn(
                "float parameter 'receive_timeout' "
                "is deprecated, please use parameter "
                "'timeout=ClientWSTimeout(ws_receive=...)'",
                DeprecationWarning,
                stacklevel=2,
            )
            ws_timeout = dataclasses.replace(ws_timeout, ws_receive=receive_timeout)

        if headers is None:
            real_headers: CIMultiDict[str] = CIMultiDict()
        else:
            real_headers = CIMultiDict(headers)

        default_headers = {
            hdrs.UPGRADE: "websocket",
            hdrs.CONNECTION: "Upgrade",
            hdrs.SEC_WEBSOCKET_VERSION: "13",
        }

        for key, value in default_headers.items():
            real_headers.setdefault(key, value)

        sec_key = base64.b64encode(os.urandom(16))
        real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()

        if protocols:
            real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ",".join(protocols)
        if origin is not None:
            real_headers[hdrs.ORIGIN] = origin
        if compress:
            extstr = ws_ext_gen(compress=compress)
            real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr

        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, Fingerprint, or bool, "
                "got {!r} instead.".format(ssl)
            )

        # send request
        resp = await self.request(
            method,
            url,
            params=params,
            headers=real_headers,
            read_until_eof=False,
            auth=auth,
            proxy=proxy,
            proxy_auth=proxy_auth,
            ssl=ssl,
            server_hostname=server_hostname,
            proxy_headers=proxy_headers,
        )

        try:
            # check handshake
            if resp.status != 101:
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid response status",
                    status=resp.status,
                    headers=resp.headers,
                )

            if resp.headers.get(hdrs.UPGRADE, "").lower() != "websocket":
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid upgrade header",
                    status=resp.status,
                    headers=resp.headers,
                )

            if resp.headers.get(hdrs.CONNECTION, "").lower() != "upgrade":
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid connection header",
                    status=resp.status,
                    headers=resp.headers,
                )

            # key calculation
            r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, "")
            match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()
            if r_key != match:
                raise WSServerHandshakeError(
                    resp.request_info,
                    resp.history,
                    message="Invalid challenge response",
                    status=resp.status,
                    headers=resp.headers,
                )

            # websocket protocol
            protocol = None
            if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:
                resp_protocols = [
                    proto.strip()
                    for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",")
                ]

                for proto in resp_protocols:
                    if proto in protocols:
                        protocol = proto
                        break

            # websocket compress
            notakeover = False
            if compress:
                compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)
                if compress_hdrs:
                    try:
                        compress, notakeover = ws_ext_parse(compress_hdrs)
                    except WSHandshakeError as exc:
                        raise WSServerHandshakeError(
                            resp.request_info,
                            resp.history,
                            message=exc.args[0],
                            status=resp.status,
                            headers=resp.headers,
                        ) from exc
                else:
                    compress = 0
                    notakeover = False

            conn = resp.connection
            assert conn is not None
            conn_proto = conn.protocol
            assert conn_proto is not None

            # For WS connection the read_timeout must be either ws_timeout.ws_receive or greater
            # None == no timeout, i.e. infinite timeout, so None is the max timeout possible
            if ws_timeout.ws_receive is None:
                # Reset regardless
                conn_proto.read_timeout = None
            elif conn_proto.read_timeout is not None:
                conn_proto.read_timeout = max(
                    ws_timeout.ws_receive, conn_proto.read_timeout
                )

            transport = conn.transport
            assert transport is not None
            reader: FlowControlDataQueue[WSMessage] = FlowControlDataQueue(
                conn_proto, 2**16, loop=self._loop
            )
            conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)
            writer = WebSocketWriter(
                conn_proto,
                transport,
                use_mask=True,
                compress=compress,
                notakeover=notakeover,
            )
        except BaseException:
            resp.close()
            raise
        else:
            return self._ws_response_class(
                reader,
                writer,
                protocol,
                resp,
                ws_timeout,
                autoclose,
                autoping,
                self._loop,
                heartbeat=heartbeat,
                compress=compress,
                client_notakeover=notakeover,
            )

    def _prepare_headers(self, headers: Optional[LooseHeaders]) -> "CIMultiDict[str]":
        """Add default headers and transform it to CIMultiDict"""
        # Convert headers to MultiDict
        result = CIMultiDict(self._default_headers)
        if headers:
            if not isinstance(headers, (MultiDictProxy, MultiDict)):
                headers = CIMultiDict(headers)
            added_names: Set[str] = set()
            for key, value in headers.items():
                if key in added_names:
                    result.add(key, value)
                else:
                    result[key] = value
                    added_names.add(key)
        return result

    if sys.version_info >= (3, 11) and TYPE_CHECKING:

        def get(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def options(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def head(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def post(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def put(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def patch(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

        def delete(
            self,
            url: StrOrURL,
            **kwargs: Unpack[_RequestOptions],
        ) -> "_RequestContextManager": ...

    else:

        def get(
            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP GET request."""
            return _RequestContextManager(
                self._request(
                    hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs
                )
            )

        def options(
            self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP OPTIONS request."""
            return _RequestContextManager(
                self._request(
                    hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs
                )
            )

        def head(
            self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP HEAD request."""
            return _RequestContextManager(
                self._request(
                    hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs
                )
            )

        def post(
            self, url: StrOrURL, *, data: Any = None, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP POST request."""
            return _RequestContextManager(
                self._request(hdrs.METH_POST, url, data=data, **kwargs)
            )

        def put(
            self, url: StrOrURL, *, data: Any = None, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP PUT request."""
            return _RequestContextManager(
                self._request(hdrs.METH_PUT, url, data=data, **kwargs)
            )

        def patch(
            self, url: StrOrURL, *, data: Any = None, **kwargs: Any
        ) -> "_RequestContextManager":
            """Perform HTTP PATCH request."""
            return _RequestContextManager(
                self._request(hdrs.METH_PATCH, url, data=data, **kwargs)
            )

        def delete(self, url: StrOrURL, **kwargs: Any) -> "_RequestContextManager":
            """Perform HTTP DELETE request."""
            return _RequestContextManager(
                self._request(hdrs.METH_DELETE, url, **kwargs)
            )

    async def close(self) -> None:
        """Close underlying connector.

        Release all acquired resources.
        """
        if not self.closed:
            if self._connector is not None and self._connector_owner:
                await self._connector.close()
            self._connector = None

    @property
    def closed(self) -> bool:
        """Is client session closed.

        A readonly property.
        """
        return self._connector is None or self._connector.closed

    @property
    def connector(self) -> Optional[BaseConnector]:
        """Connector instance used for the session."""
        return self._connector

    @property
    def cookie_jar(self) -> AbstractCookieJar:
        """The session cookies."""
        return self._cookie_jar

    @property
    def version(self) -> Tuple[int, int]:
        """The session HTTP protocol version."""
        return self._version

    @property
    def requote_redirect_url(self) -> bool:
        """Do URL requoting on redirection handling."""
        return self._requote_redirect_url

    @property
    def timeout(self) -> ClientTimeout:
        """Timeout for the session."""
        return self._timeout

    @property
    def headers(self) -> "CIMultiDict[str]":
        """The default headers of the client session."""
        return self._default_headers

    @property
    def skip_auto_headers(self) -> FrozenSet[istr]:
        """Headers for which autogeneration should be skipped"""
        return self._skip_auto_headers

    @property
    def auth(self) -> Optional[BasicAuth]:
        """An object that represents HTTP Basic Authorization"""
        return self._default_auth

    @property
    def json_serialize(self) -> JSONEncoder:
        """Json serializer callable"""
        return self._json_serialize

    @property
    def connector_owner(self) -> bool:
        """Should connector be closed on session closing"""
        return self._connector_owner

    @property
    def raise_for_status(
        self,
    ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:
        """Should `ClientResponse.raise_for_status()` be called for each response."""
        return self._raise_for_status

    @property
    def auto_decompress(self) -> bool:
        """Should the body response be automatically decompressed."""
        return self._auto_decompress

    @property
    def trust_env(self) -> bool:
        """
        Should proxies information from environment or netrc be trusted.

        Information is from HTTP_PROXY / HTTPS_PROXY environment variables
        or ~/.netrc file if present.
        """
        return self._trust_env

    @property
    def trace_configs(self) -> List[TraceConfig[Any]]:
        """A list of TraceConfig instances used for client tracing"""
        return self._trace_configs

    def detach(self) -> None:
        """Detach connector from session without closing the former.

        Session is switched to closed state anyway.
        """
        self._connector = None

    async def __aenter__(self) -> "ClientSession":
        return self

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        await self.close()


class _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]):
    __slots__ = ("_coro", "_resp")

    def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> None:
        self._coro = coro

    def send(self, arg: None) -> "asyncio.Future[Any]":
        return self._coro.send(arg)

    def throw(self, *args: Any, **kwargs: Any) -> "asyncio.Future[Any]":
        return self._coro.throw(*args, **kwargs)

    def close(self) -> None:
        return self._coro.close()

    def __await__(self) -> Generator[Any, None, _RetType]:
        ret = self._coro.__await__()
        return ret

    def __iter__(self) -> Generator[Any, None, _RetType]:
        return self.__await__()

    async def __aenter__(self) -> _RetType:
        self._resp = await self._coro
        return self._resp


class _RequestContextManager(_BaseRequestContextManager[ClientResponse]):
    __slots__ = ()

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ) -> None:
        # We're basing behavior on the exception as it can be caused by
        # user code unrelated to the status of the connection.  If you
        # would like to close a connection you must do that
        # explicitly.  Otherwise connection error handling should kick in
        # and close/recycle the connection as required.
        self._resp.release()
        await self._resp.wait_for_close()


class _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]):
    __slots__ = ()

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ) -> None:
        await self._resp.close()


class _SessionRequestContextManager:
    __slots__ = ("_coro", "_resp", "_session")

    def __init__(
        self,
        coro: Coroutine["asyncio.Future[Any]", None, ClientResponse],
        session: ClientSession,
    ) -> None:
        self._coro = coro
        self._resp: Optional[ClientResponse] = None
        self._session = session

    async def __aenter__(self) -> ClientResponse:
        try:
            self._resp = await self._coro
        except BaseException:
            await self._session.close()
            raise
        else:
            return self._resp

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ) -> None:
        assert self._resp is not None
        self._resp.close()
        await self._session.close()


def request(
    method: str,
    url: StrOrURL,
    *,
    params: Optional[Mapping[str, str]] = None,
    data: Any = None,
    json: Any = None,
    headers: Optional[LooseHeaders] = None,
    skip_auto_headers: Optional[Iterable[str]] = None,
    auth: Optional[BasicAuth] = None,
    allow_redirects: bool = True,
    max_redirects: int = 10,
    compress: Optional[str] = None,
    chunked: Optional[bool] = None,
    expect100: bool = False,
    raise_for_status: Optional[bool] = None,
    read_until_eof: bool = True,
    proxy: Optional[StrOrURL] = None,
    proxy_auth: Optional[BasicAuth] = None,
    timeout: Union[ClientTimeout, _SENTINEL] = sentinel,
    cookies: Optional[LooseCookies] = None,
    version: HttpVersion = http.HttpVersion11,
    connector: Optional[BaseConnector] = None,
    read_bufsize: Optional[int] = None,
    max_line_size: int = 8190,
    max_field_size: int = 8190,
) -> _SessionRequestContextManager:
    """Constructs and sends a request.

    Returns response object.
    method - HTTP method
    url - request url
    params - (optional) Dictionary or bytes to be sent in the query
      string of the new request
    data - (optional) Dictionary, bytes, or file-like object to
      send in the body of the request
    json - (optional) Any json compatible python object
    headers - (optional) Dictionary of HTTP Headers to send with
      the request
    cookies - (optional) Dict object to send with the request
    auth - (optional) BasicAuth named tuple represent HTTP Basic Auth
    auth - aiohttp.helpers.BasicAuth
    allow_redirects - (optional) If set to False, do not follow
      redirects
    version - Request HTTP version.
    compress - Set to True if request has to be compressed
       with deflate encoding.
    chunked - Set to chunk size for chunked transfer encoding.
    expect100 - Expect 100-continue response from server.
    connector - BaseConnector sub-class instance to support
       connection pooling.
    read_until_eof - Read response until eof if response
       does not have Content-Length header.
    loop - Optional event loop.
    timeout - Optional ClientTimeout settings structure, 5min
       total timeout by default.
    Usage::
      >>> import aiohttp
      >>> async with aiohttp.request('GET', 'http://python.org/') as resp:
      ...    print(resp)
      ...    data = await resp.read()
      <ClientResponse(https://www.python.org/) [200 OK]>
    """
    connector_owner = False
    if connector is None:
        connector_owner = True
        connector = TCPConnector(force_close=True)

    session = ClientSession(
        cookies=cookies,
        version=version,
        timeout=timeout,
        connector=connector,
        connector_owner=connector_owner,
    )

    return _SessionRequestContextManager(
        session._request(
            method,
            url,
            params=params,
            data=data,
            json=json,
            headers=headers,
            skip_auto_headers=skip_auto_headers,
            auth=auth,
            allow_redirects=allow_redirects,
            max_redirects=max_redirects,
            compress=compress,
            chunked=chunked,
            expect100=expect100,
            raise_for_status=raise_for_status,
            read_until_eof=read_until_eof,
            proxy=proxy,
            proxy_auth=proxy_auth,
            read_bufsize=read_bufsize,
            max_line_size=max_line_size,
            max_field_size=max_field_size,
        ),
        session,
    )

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user