]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Better HTTP/2 defaults. (#584)
authorTom Christie <tom@tomchristie.com>
Mon, 2 Dec 2019 17:07:04 +0000 (17:07 +0000)
committerGitHub <noreply@github.com>
Mon, 2 Dec 2019 17:07:04 +0000 (17:07 +0000)
* Simplify HTTP version config, and switch HTTP/2 off by default

* HTTP/2 docs

* HTTP/2 interlinking in docs

16 files changed:
docs/advanced.md
docs/http2.md [new file with mode: 0644]
docs/index.md
httpx/__init__.py
httpx/api.py
httpx/client.py
httpx/config.py
httpx/dispatch/connection.py
httpx/dispatch/connection_pool.py
httpx/dispatch/proxy_http.py
mkdocs.yml
tests/client/test_proxies.py
tests/dispatch/test_http2.py
tests/test_concurrency.py
tests/test_config.py
tests/test_multipart.py

index d087bd255e99fee4ca3024d396adeca1e94192c5..9b1502fa2f8cf9e2b96824a1e26538e3e47fa833 100644 (file)
@@ -141,20 +141,6 @@ make modifications before sending the request.
 <Response [200 OK]>
 ```
 
-## Specify the version of the HTTP protocol
-
-One can set the version of the HTTP protocol for the client in case you want to make the requests using a specific version.
-
-For example:
-
-```python
-async with httpx.Client(http_versions=["HTTP/1.1"]) as h11_client:
-    h11_response = await h11_client.get("https://myserver.com")
-
-async with httpx.Client(http_versions=["HTTP/2"]) as h2_client:
-    h2_response = await h2_client.get("https://myserver.com")
-```
-
 ## .netrc Support
 
 HTTPX supports .netrc file. In `trust_env=True` cases, if auth parameter is
@@ -367,7 +353,7 @@ More specifically, if a tuple is used as a value, it must have between 2 and 3 e
 - The first element is an optional file name which can be set to `None`.
 - The second element may be a file-like object or a string which will be automatically
 encoded in UTF-8.
-- An optional third element can be used to specify the 
+- An optional third element can be used to specify the
 [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_Types)
 of the file being uploaded. If not specified HTTPX will attempt to guess the MIME type based
 on the file name, with unknown file extensions defaulting to "application/octet-stream".
diff --git a/docs/http2.md b/docs/http2.md
new file mode 100644 (file)
index 0000000..66d835d
--- /dev/null
@@ -0,0 +1,60 @@
+# HTTP/2
+
+HTTP/2 is a major new iteration of the HTTP protocol, that provides a far more
+efficient transport, with potential performance benefits. HTTP/2 does not change
+the core semantics of the request or response, but alters the way that data is
+sent to and from the server.
+
+Rather that the text format that HTTP/1.1 uses, HTTP/2 is a binary format.
+The binary format provides full request and response multiplexing, and efficient
+compression of HTTP headers. The stream multiplexing means that where HTTP/1.1
+requires one TCP stream for each concurrent request, HTTP/2 allows a single TCP
+stream to handle multiple concurrent requests.
+
+HTTP/2 also provides support for functionality such as response prioritization,
+and server push.
+
+For a comprehensive guide to HTTP/2 you may want to check out "[HTTP2 Explained](https://http2-explained.haxx.se/content/en/)".
+
+## Enabling HTTP/2
+
+The HTTPX client provides provisional HTTP/2 support.
+
+HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature,
+battle-hardened transport layer. With HTTP/2 being newer and significantly more
+complex, our implementation should be considered a less robust option at this
+point in time.
+
+However, if you're issuing highly concurrent requests you might want to consider
+trying out our HTTP/2 support. You can do so by instantiating a client with
+HTTP/2 support enabled:
+
+```python
+client = httpx.Client(http_2=True)
+...
+```
+
+You can also instantiate a client as a context manager, to ensure that all
+HTTP connections are nicely scoped, and will be closed once the context block
+is exited.
+
+```python
+async with httpx.Client(http_2=True) as client:
+    ...
+```
+
+## Inspecting the HTTP version
+
+Enabling HTTP/2 support on the client does not *necessarily* mean that your
+requests and responses will be transported over HTTP/2, since both the client
+*and* the server need to support HTTP/2. If you connect to a server that only
+supports HTTP/1.1 the client will use a standard HTTP/1.1 connection instead.
+
+You can determine which version of the HTTP protocol was used by examining
+the `.http_version` property on the response.
+
+```python
+client = httpx.Client(http_2=True)
+response = await client.get(...)
+print(response.http_version)  # "HTTP/1.0", "HTTP/1.1", or "HTTP/2".
+```
index 846d58a49624539d3a0de61324286c7b04b91848..c233494c926871c053d7808708a5225d15270dc0 100644 (file)
@@ -64,7 +64,7 @@ HTTPX is a high performance asynchronous HTTP client, that builds on the
 well-established usability of `requests`, and gives you:
 
 * A broadly requests-compatible API.
-* HTTP/2 and HTTP/1.1 support.
+* HTTP/1.1 and [HTTP/2 support](http2.md).
 * Ability to [make requests directly to ASGI applications](advanced.md#calling-into-python-web-apps).
 * Strict timeouts everywhere.
 * Fully type annotated.
@@ -92,7 +92,8 @@ Plus all the standard features of `requests`...
 
 For a run-through of all the basics, head over to the [QuickStart](quickstart.md).
 
-For more advanced topics, see the [Advanced Usage](advanced.md) section.
+For more advanced topics, see the [Advanced Usage](advanced.md) section,
+or the [HTTP/2](http2.md) section.
 
 The [Developer Interface](api.md) provides a comprehensive API reference.
 
index bda76ae309ccac6058e0459b3e0a4421803e84e9..0910545bdf3df94ce1c3cefd69d21c4ddfe96fbb 100644 (file)
@@ -12,8 +12,6 @@ from .concurrency.base import (
 from .config import (
     USER_AGENT,
     CertTypes,
-    HTTPVersionConfig,
-    HTTPVersionTypes,
     PoolLimits,
     SSLConfig,
     TimeoutConfig,
@@ -118,8 +116,6 @@ __all__ = [
     "StatusCode",
     "codes",
     "TimeoutTypes",
-    "HTTPVersionTypes",
-    "HTTPVersionConfig",
     "AuthTypes",
     "Cookies",
     "CookieTypes",
index 2ea1be62bbba2447808feeeb59c5c91fc6660541..893c3e73cb5f5261ea021a6bd746a38e3ec5f472 100644 (file)
@@ -81,11 +81,7 @@ async def request(
     ```
     """
     async with Client(
-        http_versions=["HTTP/1.1"],
-        cert=cert,
-        verify=verify,
-        timeout=timeout,
-        trust_env=trust_env,
+        cert=cert, verify=verify, timeout=timeout, trust_env=trust_env,
     ) as client:
         return await client.request(
             method=method,
index 1fe4f6c0143ee73b1d92e1b00867315397a14a44..28aa1767ecaf2f8e27b4839061598a0cde6b795d 100644 (file)
@@ -12,7 +12,6 @@ from .config import (
     DEFAULT_POOL_LIMITS,
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionTypes,
     PoolLimits,
     TimeoutTypes,
     VerifyTypes,
@@ -79,8 +78,8 @@ class Client:
     to authenticate the client. Either a path to an SSL certificate file, or
     two-tuple of (certificate file, key file), or a three-tuple of (certificate
     file, key file, password).
-    * **http_versions** - *(optional)* A list of strings of HTTP protocol
-    versions to use when sending requests. eg. `http_versions=["HTTP/1.1"]`
+    * **http_2** - *(optional)* A boolean indicating if HTTP/2 support should be
+    enabled. Defaults to `False`.
     * **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy
     URLs.
     * **timeout** - *(optional)* The timeout configuration to use when sending
@@ -111,7 +110,7 @@ class Client:
         cookies: CookieTypes = None,
         verify: VerifyTypes = True,
         cert: CertTypes = None,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         proxies: ProxiesTypes = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
         pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
@@ -134,7 +133,7 @@ class Client:
                 verify=verify,
                 cert=cert,
                 timeout=timeout,
-                http_versions=http_versions,
+                http_2=http_2,
                 pool_limits=pool_limits,
                 backend=backend,
                 trust_env=trust_env,
@@ -167,7 +166,7 @@ class Client:
             verify=verify,
             cert=cert,
             timeout=timeout,
-            http_versions=http_versions,
+            http_2=http_2,
             pool_limits=pool_limits,
             backend=backend,
             trust_env=trust_env,
@@ -833,13 +832,13 @@ def _proxies_to_dispatchers(
     verify: VerifyTypes,
     cert: typing.Optional[CertTypes],
     timeout: TimeoutTypes,
-    http_versions: typing.Optional[HTTPVersionTypes],
+    http_2: bool,
     pool_limits: PoolLimits,
     backend: ConcurrencyBackend,
     trust_env: bool,
 ) -> typing.Dict[str, Dispatcher]:
     def _proxy_from_url(url: URLTypes) -> Dispatcher:
-        nonlocal verify, cert, timeout, http_versions, pool_limits, backend, trust_env
+        nonlocal verify, cert, timeout, http_2, pool_limits, backend, trust_env
         url = URL(url)
         if url.scheme in ("http", "https"):
             return HTTPProxy(
@@ -850,7 +849,7 @@ def _proxies_to_dispatchers(
                 pool_limits=pool_limits,
                 backend=backend,
                 trust_env=trust_env,
-                http_versions=http_versions,
+                http_2=http_2,
             )
         raise ValueError(f"Unknown proxy for {url!r}")
 
index a32ae84df9599daf373c309cdc858f88746b049a..cace3c20dd51b41e58aeace93f4b0c6f2a2ea3fb 100644 (file)
@@ -13,15 +13,10 @@ VerifyTypes = typing.Union[str, bool, ssl.SSLContext]
 TimeoutTypes = typing.Union[
     float, typing.Tuple[float, float, float, float], "TimeoutConfig"
 ]
-HTTPVersionTypes = typing.Union[
-    str, typing.List[str], typing.Tuple[str], "HTTPVersionConfig"
-]
 
 
 USER_AGENT = f"python-httpx/{__version__}"
 
-HTTP_VERSIONS_TO_ALPN_IDENTIFIERS = {"HTTP/1.1": "http/1.1", "HTTP/2": "h2"}
-
 DEFAULT_CIPHERS = ":".join(
     [
         "ECDHE+AESGCM",
@@ -91,43 +86,35 @@ class SSLConfig:
             return self
         return SSLConfig(cert=cert, verify=verify)
 
-    def load_ssl_context(
-        self, http_versions: "HTTPVersionConfig" = None
-    ) -> ssl.SSLContext:
-        http_versions = HTTPVersionConfig() if http_versions is None else http_versions
-
+    def load_ssl_context(self, http_2: bool = False) -> ssl.SSLContext:
         logger.trace(
             f"load_ssl_context "
             f"verify={self.verify!r} "
             f"cert={self.cert!r} "
             f"trust_env={self.trust_env!r} "
-            f"http_versions={http_versions!r}"
+            f"http_2={http_2!r}"
         )
 
         if self.ssl_context is None:
             self.ssl_context = (
-                self.load_ssl_context_verify(http_versions=http_versions)
+                self.load_ssl_context_verify(http_2=http_2)
                 if self.verify
-                else self.load_ssl_context_no_verify(http_versions=http_versions)
+                else self.load_ssl_context_no_verify(http_2=http_2)
             )
 
         assert self.ssl_context is not None
         return self.ssl_context
 
-    def load_ssl_context_no_verify(
-        self, http_versions: "HTTPVersionConfig"
-    ) -> ssl.SSLContext:
+    def load_ssl_context_no_verify(self, http_2: bool = False) -> ssl.SSLContext:
         """
         Return an SSL context for unverified connections.
         """
-        context = self._create_default_ssl_context(http_versions=http_versions)
+        context = self._create_default_ssl_context(http_2=http_2)
         context.verify_mode = ssl.CERT_NONE
         context.check_hostname = False
         return context
 
-    def load_ssl_context_verify(
-        self, http_versions: "HTTPVersionConfig"
-    ) -> ssl.SSLContext:
+    def load_ssl_context_verify(self, http_2: bool = False) -> ssl.SSLContext:
         """
         Return an SSL context for verified connections.
         """
@@ -146,7 +133,7 @@ class SSLConfig:
                 "invalid path: {}".format(self.verify)
             )
 
-        context = self._create_default_ssl_context(http_versions=http_versions)
+        context = self._create_default_ssl_context(http_2=http_2)
         context.verify_mode = ssl.CERT_REQUIRED
         context.check_hostname = True
 
@@ -175,9 +162,7 @@ class SSLConfig:
 
         return context
 
-    def _create_default_ssl_context(
-        self, http_versions: "HTTPVersionConfig"
-    ) -> ssl.SSLContext:
+    def _create_default_ssl_context(self, http_2: bool) -> ssl.SSLContext:
         """
         Creates the default SSLContext object that's used for both verified
         and unverified connections.
@@ -191,7 +176,8 @@ class SSLConfig:
         context.set_ciphers(DEFAULT_CIPHERS)
 
         if ssl.HAS_ALPN:
-            context.set_alpn_protocols(http_versions.alpn_identifiers)
+            alpn_idents = ["http/1.1", "h2"] if http_2 else ["http/1.1"]
+            context.set_alpn_protocols(alpn_idents)
 
         if hasattr(context, "keylog_filename"):
             keylogfile = os.environ.get("SSLKEYLOGFILE")
@@ -288,52 +274,6 @@ class TimeoutConfig:
         )
 
 
-class HTTPVersionConfig:
-    """
-    Configure which HTTP protocol versions are supported.
-    """
-
-    def __init__(self, http_versions: HTTPVersionTypes = None):
-        if http_versions is None:
-            http_versions = ["HTTP/1.1", "HTTP/2"]
-
-        if isinstance(http_versions, str):
-            self.http_versions = {http_versions.upper()}
-        elif isinstance(http_versions, HTTPVersionConfig):
-            self.http_versions = http_versions.http_versions
-        elif isinstance(http_versions, typing.Iterable):
-            self.http_versions = {
-                version.upper() if isinstance(version, str) else version
-                for version in http_versions
-            }
-        else:
-            raise TypeError(
-                "HTTP version should be a string or list of strings, "
-                f"but got {type(http_versions)}"
-            )
-
-        for version in self.http_versions:
-            if version not in ("HTTP/1.1", "HTTP/2"):
-                raise ValueError(f"Unsupported HTTP version {version!r}.")
-
-        if not self.http_versions:
-            raise ValueError("HTTP versions cannot be an empty list.")
-
-    @property
-    def alpn_identifiers(self) -> typing.List[str]:
-        """
-        Returns a list of supported ALPN identifiers. (One or more of "http/1.1", "h2").
-        """
-        return [
-            HTTP_VERSIONS_TO_ALPN_IDENTIFIERS[version] for version in self.http_versions
-        ]
-
-    def __repr__(self) -> str:
-        class_name = self.__class__.__name__
-        value = sorted(list(self.http_versions))
-        return f"{class_name}({value!r})"
-
-
 class PoolLimits:
     """
     Limits on the number of connections in a connection pool.
index 6694caa2deb06312bab84cdfd01f2f1b3824b140..0f05b2e8b211994c42c60ba61d138f4bf5166920 100644 (file)
@@ -7,8 +7,6 @@ from ..concurrency.base import ConcurrencyBackend
 from ..config import (
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionConfig,
-    HTTPVersionTypes,
     SSLConfig,
     TimeoutConfig,
     TimeoutTypes,
@@ -35,7 +33,7 @@ class HTTPConnection(Dispatcher):
         cert: CertTypes = None,
         trust_env: bool = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         backend: ConcurrencyBackend = None,
         release_func: typing.Optional[ReleaseCallback] = None,
         uds: typing.Optional[str] = None,
@@ -43,7 +41,7 @@ class HTTPConnection(Dispatcher):
         self.origin = Origin(origin) if isinstance(origin, str) else origin
         self.ssl = SSLConfig(cert=cert, verify=verify, trust_env=trust_env)
         self.timeout = TimeoutConfig(timeout)
-        self.http_versions = HTTPVersionConfig(http_versions)
+        self.http_2 = http_2
         self.backend = AsyncioBackend() if backend is None else backend
         self.release_func = release_func
         self.uds = uds
@@ -119,9 +117,7 @@ class HTTPConnection(Dispatcher):
             return None
 
         # Run the SSL loading in a threadpool, since it may make disk accesses.
-        return await self.backend.run_in_threadpool(
-            ssl.load_ssl_context, self.http_versions
-        )
+        return await self.backend.run_in_threadpool(ssl.load_ssl_context, self.http_2)
 
     async def close(self) -> None:
         logger.trace("close_connection")
index 32173301b713fdcfd1e35c3e702fd5a1cff248c9..fc44c413016e1f69579c768f0906172c1edcd79d 100644 (file)
@@ -6,7 +6,6 @@ from ..config import (
     DEFAULT_POOL_LIMITS,
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionTypes,
     PoolLimits,
     TimeoutConfig,
     TimeoutTypes,
@@ -88,7 +87,7 @@ class ConnectionPool(Dispatcher):
         trust_env: bool = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
         pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         backend: ConcurrencyBackend = None,
         uds: typing.Optional[str] = None,
     ):
@@ -96,7 +95,7 @@ class ConnectionPool(Dispatcher):
         self.cert = cert
         self.timeout = TimeoutConfig(timeout)
         self.pool_limits = pool_limits
-        self.http_versions = http_versions
+        self.http_2 = http_2
         self.is_closed = False
         self.trust_env = trust_env
         self.uds = uds
@@ -150,7 +149,7 @@ class ConnectionPool(Dispatcher):
                 verify=self.verify,
                 cert=self.cert,
                 timeout=self.timeout,
-                http_versions=self.http_versions,
+                http_2=self.http_2,
                 backend=self.backend,
                 release_func=self.release_connection,
                 trust_env=self.trust_env,
index 13eb42333e3162943412aae49218848580bd622b..c51c009e120f807c0500770b4cf89866c23fb609 100644 (file)
@@ -8,7 +8,6 @@ from ..config import (
     DEFAULT_POOL_LIMITS,
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionTypes,
     PoolLimits,
     SSLConfig,
     TimeoutTypes,
@@ -47,7 +46,7 @@ class HTTPProxy(ConnectionPool):
         trust_env: bool = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
         pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         backend: ConcurrencyBackend = None,
     ):
 
@@ -58,7 +57,7 @@ class HTTPProxy(ConnectionPool):
             pool_limits=pool_limits,
             backend=backend,
             trust_env=trust_env,
-            http_versions=http_versions,
+            http_2=http_2,
         )
 
         self.proxy_url = URL(proxy_url)
@@ -134,7 +133,7 @@ class HTTPProxy(ConnectionPool):
             cert=self.cert,
             timeout=self.timeout,
             backend=self.backend,
-            http_versions=["HTTP/1.1"],  # Short-lived 'connection'
+            http_2=False,  # Short-lived 'connection'
             trust_env=self.trust_env,
             release_func=self.release_connection,
         )
index 0ddd8c85b6c6c2e544b929a3e09813a1001f689e..a2a733c935fa125ffeddabd1082cc80cd76afb73 100644 (file)
@@ -12,6 +12,7 @@ nav:
     - Introduction: 'index.md'
     - QuickStart: 'quickstart.md'
     - Advanced Usage: 'advanced.md'
+    - HTTP/2 Support: 'http2.md'
     - Environment Variables: 'environment_variables.md'
     - Requests Compatibility: 'compatibility.md'
     - Developer Interface: 'api.md'
index fc1e57a5e851e887dbef4604bc8584242be8bb21..ede15a8fce1ced4d304f0d20c12153c980a34400 100644 (file)
@@ -36,7 +36,6 @@ def test_proxies_has_same_properties_as_dispatch():
         cert="/path/to/cert",
         trust_env=False,
         timeout=30,
-        http_versions=["HTTP/1.1"],
     )
     pool = client.dispatch
     proxy = client.proxies["all"]
@@ -49,7 +48,6 @@ def test_proxies_has_same_properties_as_dispatch():
         "cert",
         "timeout",
         "pool_limits",
-        "http_versions",
         "backend",
     ]:
         assert getattr(pool, prop) == getattr(proxy, prop)
index 0c8c9177be65f96e3183ded1a619b4a7cdb5a228..86dcc8ff26d4b508fffdedd2777dfd98422026d3 100644 (file)
@@ -27,7 +27,7 @@ def app(request):
 async def test_http2_get_request():
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response = await client.get("http://example.org")
 
     assert response.status_code == 200
@@ -38,7 +38,7 @@ async def test_http2_get_request():
 async def test_http2_post_request():
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response = await client.post("http://example.org", data=b"<data>")
 
     assert response.status_code == 200
@@ -54,7 +54,7 @@ async def test_http2_large_post_request():
     backend = MockHTTP2Backend(app=app)
 
     data = b"a" * 100000
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response = await client.post("http://example.org", data=data)
     assert response.status_code == 200
     assert json.loads(response.content) == {
@@ -68,7 +68,7 @@ async def test_http2_large_post_request():
 async def test_http2_multiple_requests():
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response_1 = await client.get("http://example.org/1")
         response_2 = await client.get("http://example.org/2")
         response_3 = await client.get("http://example.org/3")
@@ -91,7 +91,7 @@ async def test_http2_reconnect():
     """
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response_1 = await client.get("http://example.org/1")
         backend.server.close_connection = True
         response_2 = await client.get("http://example.org/2")
@@ -106,7 +106,7 @@ async def test_http2_reconnect():
 async def test_http2_settings_in_handshake(backend):
     backend = MockHTTP2Backend(app=app, backend=backend)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         await client.get("http://example.org")
 
     h2_conn = backend.server.conn
@@ -139,7 +139,7 @@ async def test_http2_settings_in_handshake(backend):
 
 
 async def test_http2_live_request(backend):
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         try:
             resp = await client.get("https://nghttp2.org/httpbin/anything")
         except Timeout:
index da43987f0cb461ccac506168238be310578fa1c9..52828dacff09f29ff6034896e8b6d7ff69ce27f5 100644 (file)
@@ -1,7 +1,7 @@
 import pytest
 import trio
 
-from httpx import AsyncioBackend, HTTPVersionConfig, SSLConfig, TimeoutConfig
+from httpx import AsyncioBackend, SSLConfig, TimeoutConfig
 from httpx.concurrency.trio import TrioBackend
 from tests.concurrency import run_concurrently
 
@@ -40,7 +40,7 @@ async def read_response(stream, timeout: float, should_contain: bytes) -> bytes:
     ],
 )
 async def test_start_tls_on_tcp_socket_stream(https_server, backend, get_cipher):
-    ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig())
+    ctx = SSLConfig().load_ssl_context_no_verify()
     timeout = TimeoutConfig(5)
 
     stream = await backend.open_tcp_stream(
@@ -72,7 +72,7 @@ async def test_start_tls_on_tcp_socket_stream(https_server, backend, get_cipher)
     ],
 )
 async def test_start_tls_on_uds_socket_stream(https_uds_server, backend, get_cipher):
-    ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig())
+    ctx = SSLConfig().load_ssl_context_no_verify()
     timeout = TimeoutConfig(5)
 
     stream = await backend.open_uds_stream(
index 6f8d808b2c5658d0862f4df6194f4822b9153806..1835ec74aedfc1237dcfa592a48a65cee8296637 100644 (file)
@@ -118,46 +118,6 @@ def test_ssl_repr():
     assert repr(ssl) == "SSLConfig(cert=None, verify=False)"
 
 
-def test_http_versions_repr():
-    http_versions = httpx.HTTPVersionConfig()
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1', 'HTTP/2'])"
-
-
-def test_http_versions_from_string():
-    http_versions = httpx.HTTPVersionConfig("HTTP/1.1")
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1'])"
-
-
-def test_http_versions_from_list():
-    http_versions = httpx.HTTPVersionConfig(["http/1.1"])
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1'])"
-
-
-def test_http_versions_from_config():
-    http_versions = httpx.HTTPVersionConfig(httpx.HTTPVersionConfig("HTTP/1.1"))
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1'])"
-
-
-def test_invalid_http_version():
-    with pytest.raises(ValueError):
-        httpx.HTTPVersionConfig("HTTP/9")
-
-
-def test_invalid_http_version_type():
-    with pytest.raises(TypeError):
-        httpx.HTTPVersionConfig(123)
-
-
-def test_invalid_http_version_list_type():
-    with pytest.raises(ValueError):
-        httpx.HTTPVersionConfig([123])
-
-
-def test_empty_http_version():
-    with pytest.raises(ValueError):
-        httpx.HTTPVersionConfig([])
-
-
 def test_limits_repr():
     limits = httpx.PoolLimits(hard_limit=100)
     assert repr(limits) == "PoolLimits(soft_limit=None, hard_limit=100)"
index 3936a05de7bf8aee0ffae2d5c240a1c94b310da5..b5e2290a7f788f3b65673f938bda6c829116043a 100644 (file)
@@ -10,7 +10,6 @@ from httpx import (
     CertTypes,
     Client,
     Dispatcher,
-    HTTPVersionTypes,
     Request,
     Response,
     TimeoutTypes,
@@ -26,7 +25,6 @@ class MockDispatch(Dispatcher):
         verify: VerifyTypes = None,
         cert: CertTypes = None,
         timeout: TimeoutTypes = None,
-        http_versions: HTTPVersionTypes = None,
     ) -> Response:
         content = await request.read()
         return Response(200, content=content)