From 0ad46ac95c8f0b9af8852a80ff9766f98f47879b Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 6 Nov 2019 18:52:46 +0100 Subject: [PATCH 1/6] Add docs on SSL certificates --- docs/advanced.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/advanced.md b/docs/advanced.md index f0d402ba63..3b258e8a10 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -362,3 +362,41 @@ is set to `None` or it cannot be inferred from it, HTTPX will default to ... } ``` + +## SSL certificates + +!!! warning + This is an advanced section. You most likely won't need to use the features documented here, unless you know what you're doing. + +When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates delivered by a trusted certificate authority (CA). + +By default, HTTPX uses the CA bundle provided by [Certifi](https://pypi.org/project/certifi/). This works fine in most cases, however in some advanced situations you may want to tweak this. + +### Using a custom CA bundle + +If you'd like to use a custom CA bundle, you can use the `verify` parameter that is available on the high-level API as well as clients. For example: + +```python +import httpx + +r = httpx.get("https://example.org", verify="path/to/client.pem") +``` + +### Making HTTPS requests to a local server + +In some cases, such as when using HTTPX to make requests against a development server, you may want to make HTTPS requests to a local server, i.e. a server running on `localhost` (a.k.a. `127.0.0.1`, the loopback address). + +Because `localhost` is a local and non-uniquely owned domain, you'll need to create your own certificates. + +Here's one way to do this, and then use them in HTTPX: + +1. Use [trustme-cli](https://github.com/sethmlarson/trustme-cli/) to generate a pair of server key/cert files, and a client cert file. +1. Pass the server key/cert files when starting your local server. (This depends on the particular web server you're using. For example, [Uvicorn](https://www.uvicorn.org) provides the `--ssl-keyfile` and `--ssl-certfile` options.) +1. Tell HTTPX to use the certificates stored in `client.pem`: + +```python +>>> import httpx +>>> r = httpx.get("https://localhost:8000", verify="/tmp/client.pem") +>>> r +Response <200 OK> +``` From 8631474924052d8cb4a75e8a9a53e04f17abd436 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 6 Nov 2019 22:29:51 +0100 Subject: [PATCH 2/6] Update docs on verify and cert params --- httpx/api.py | 9 ++++++--- httpx/client.py | 16 +++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/httpx/api.py b/httpx/api.py index 82fc48dc59..1e01983c72 100644 --- a/httpx/api.py +++ b/httpx/api.py @@ -27,8 +27,8 @@ def request( auth: AuthTypes = None, timeout: TimeoutTypes = None, allow_redirects: bool = True, - cert: CertTypes = None, verify: VerifyTypes = True, + cert: CertTypes = None, stream: bool = False, trust_env: bool = None, ) -> Response: @@ -57,10 +57,13 @@ def request( * **timeout** - *(optional)* The timeout configuration to use when sending the request. * **allow_redirects** - *(optional)* Enables or disables HTTP redirects. - * **cert** - *(optional)* Either a path to an SSL certificate file, or + * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to + verify the identity of requested hosts. Either `True` (default CA bundle), + a path to an SSL certificate file, or `False` (disable verification). + * **cert** - *(optional)* An SSL certificate used by the requested host + 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). - * **verify** - *(optional)* Enables or disables SSL verification. * **trust_env** - *(optional)* Enables or disables usage of environment variables for configuration. * **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy diff --git a/httpx/client.py b/httpx/client.py index 060dad0a65..fb1a22f8bb 100644 --- a/httpx/client.py +++ b/httpx/client.py @@ -686,8 +686,11 @@ class Client(BaseClient): sending requests. * **cookies** - *(optional)* Dictionary of Cookie items to include when sending requests. - * **verify** - *(optional)* Enables or disables SSL verification. - * **cert** - *(optional)* Either a path to an SSL certificate file, or + * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to + verify the identity of requested hosts. Either `True` (default CA bundle), + a path to an SSL certificate file, or `False` (disable verification). + * **cert** - *(optional)* An SSL certificate used by the requested host + 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 @@ -768,8 +771,8 @@ def request( stream: bool = False, auth: AuthTypes = None, allow_redirects: bool = True, - cert: CertTypes = None, verify: VerifyTypes = None, + cert: CertTypes = None, timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: @@ -797,10 +800,13 @@ def request( * **auth** - *(optional)* An authentication class to use when sending the request. * **allow_redirects** - *(optional)* Enables or disables HTTP redirects. - * **cert** - *(optional)* Either a path to an SSL certificate file, or + * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to + verify the identity of requested hosts. Either `True` (default CA bundle), + a path to an SSL certificate file, or `False` (disable verification). + * **cert** - *(optional)* An SSL certificate used by the requested host + 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). - * **verify** - *(optional)* Enables or disables SSL verification. * **timeout** - *(optional)* The timeout configuration to use when sending the request. * **trust_env** - *(optional)* Enables or disables usage of environment From d36b1f5d1384bc2f97f2fc05e7fee17b2a6142b8 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 6 Nov 2019 22:37:06 +0100 Subject: [PATCH 3/6] Tweak wording --- docs/advanced.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index 3b258e8a10..6fc73fcc2d 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -366,11 +366,13 @@ is set to `None` or it cannot be inferred from it, HTTPX will default to ## SSL certificates !!! warning - This is an advanced section. You most likely won't need to use the features documented here, unless you know what you're doing. + This is an advanced section. You typically won't need this, unless you have special needs regarding your SSL configuration. -When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates delivered by a trusted certificate authority (CA). +When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates (a.k.a. CA bundle) delivered by a trusted certificate authority (CA). -By default, HTTPX uses the CA bundle provided by [Certifi](https://pypi.org/project/certifi/). This works fine in most cases, however in some advanced situations you may want to tweak this. +### Default CA bundle + +By default, HTTPX uses the CA bundle provided by [Certifi](https://pypi.org/project/certifi/). This is what you want in most cases, even though some advanced situations may require you to use a different set of certificates. ### Using a custom CA bundle From c737881dd59a47732845deac989ebdc5049ceb12 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 6 Nov 2019 22:41:06 +0100 Subject: [PATCH 4/6] Tweak wording about localhost --- docs/advanced.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index 6fc73fcc2d..b3f6100503 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -386,11 +386,11 @@ r = httpx.get("https://example.org", verify="path/to/client.pem") ### Making HTTPS requests to a local server -In some cases, such as when using HTTPX to make requests against a development server, you may want to make HTTPS requests to a local server, i.e. a server running on `localhost` (a.k.a. `127.0.0.1`, the loopback address). +In some situations, you may have to make HTTPS requests to a server running on `localhost` (a.k.a. `127.0.0.1`, the loopback address). This is typically the case, for example, if you are making requests to a development server. -Because `localhost` is a local and non-uniquely owned domain, you'll need to create your own certificates. +Because `localhost` is a local and non-uniquely owned domain, you'll need to create your own certificates for HTTPS to work. -Here's one way to do this, and then use them in HTTPX: +Here's one way to create such certificates, and then use them in HTTPX: 1. Use [trustme-cli](https://github.com/sethmlarson/trustme-cli/) to generate a pair of server key/cert files, and a client cert file. 1. Pass the server key/cert files when starting your local server. (This depends on the particular web server you're using. For example, [Uvicorn](https://www.uvicorn.org) provides the `--ssl-keyfile` and `--ssl-certfile` options.) From a26a837a5016f870a54237cb5b070008067b1010 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 6 Nov 2019 23:04:30 +0100 Subject: [PATCH 5/6] Remove advanced warning --- docs/advanced.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index b3f6100503..ac15d397f0 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -365,9 +365,6 @@ is set to `None` or it cannot be inferred from it, HTTPX will default to ## SSL certificates -!!! warning - This is an advanced section. You typically won't need this, unless you have special needs regarding your SSL configuration. - When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates (a.k.a. CA bundle) delivered by a trusted certificate authority (CA). ### Default CA bundle From 213ce9eeb1f43a0d9fa4308944eff8334c5264fd Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 6 Nov 2019 23:07:59 +0100 Subject: [PATCH 6/6] Rephrase introduction of local HTTPS section --- docs/advanced.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index ac15d397f0..3e73f5b573 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -383,11 +383,9 @@ r = httpx.get("https://example.org", verify="path/to/client.pem") ### Making HTTPS requests to a local server -In some situations, you may have to make HTTPS requests to a server running on `localhost` (a.k.a. `127.0.0.1`, the loopback address). This is typically the case, for example, if you are making requests to a development server. +When making requests to local servers, such as a development server running on `localhost`, you will typically be using unencrypted HTTP connections. -Because `localhost` is a local and non-uniquely owned domain, you'll need to create your own certificates for HTTPS to work. - -Here's one way to create such certificates, and then use them in HTTPX: +If you do need to make HTTPS connections to a local server, for example to test an HTTPS-only service, you will need to create and use your own certificates. Here's one way to do it: 1. Use [trustme-cli](https://github.com/sethmlarson/trustme-cli/) to generate a pair of server key/cert files, and a client cert file. 1. Pass the server key/cert files when starting your local server. (This depends on the particular web server you're using. For example, [Uvicorn](https://www.uvicorn.org) provides the `--ssl-keyfile` and `--ssl-certfile` options.)