| 125 | |
| 126 | |
| 127 | class H2Agent: |
| 128 | def __init__( |
| 129 | self, |
| 130 | reactor: ReactorBase, |
| 131 | pool: H2ConnectionPool, |
| 132 | context_factory: BrowserLikePolicyForHTTPS = BrowserLikePolicyForHTTPS(), # noqa: B008 |
| 133 | connect_timeout: float | None = None, |
| 134 | bind_address: tuple[str, int] | None = None, |
| 135 | ) -> None: |
| 136 | self._reactor = reactor |
| 137 | self._pool = pool |
| 138 | self._context_factory = _AcceptableProtocolsContextFactory( |
| 139 | context_factory, acceptable_protocols=[b"h2"] |
| 140 | ) |
| 141 | self.endpoint_factory = _StandardEndpointFactory( |
| 142 | self._reactor, self._context_factory, connect_timeout, bind_address |
| 143 | ) |
| 144 | |
| 145 | def get_endpoint(self, uri: URI) -> HostnameEndpoint: |
| 146 | return self.endpoint_factory.endpointForURI(uri) # type: ignore[no-any-return] |
| 147 | |
| 148 | def get_key(self, uri: URI) -> ConnectionKeyT: |
| 149 | """ |
| 150 | Arguments: |
| 151 | uri - URI obtained directly from request URL |
| 152 | """ |
| 153 | return uri.scheme, uri.host, uri.port |
| 154 | |
| 155 | def request(self, request: Request, spider: Spider) -> Deferred[Response]: |
| 156 | uri = URI.fromBytes(bytes(request.url, encoding="utf-8")) |
| 157 | try: |
| 158 | endpoint = self.get_endpoint(uri) |
| 159 | except SchemeNotSupported: |
| 160 | return defer.fail(Failure()) |
| 161 | |
| 162 | key = self.get_key(uri) |
| 163 | d: Deferred[H2ClientProtocol] = self._pool.get_connection(key, uri, endpoint) |
| 164 | d2: Deferred[Response] = d.addCallback( |
| 165 | lambda conn: conn.request(request, spider) |
| 166 | ) |
| 167 | return d2 |