@@ -156,3 +156,60 @@ Before releasing a new version, create a pull request that includes:
156156For an example, see [ #362 ] ( https://github.com/encode/httpx/pull/362 ) .
157157
158158Once the release PR is merged, run ` $ scripts/publish ` to publish the new release to PyPI.
159+
160+ ## Development proxy setup
161+
162+ To test and debug requests via a proxy it's best to run a proxy server locally.
163+ Any server should do but HTTPCore's test suite uses
164+ [ ` mitmproxy ` ] ( https://mitmproxy.org/ ) which is written in Python, it's fully
165+ featured and has excellent UI and tools for introspection of requests.
166+
167+ You can install ` mitmproxy ` using ` pip install mitmproxy ` or [ several
168+ other ways] ( https://docs.mitmproxy.org/stable/overview-installation/ ) .
169+
170+ ` mitmproxy ` does require setting up local TLS certificates for HTTPS requests,
171+ as its main purpose is to allow developers to inspect requests that pass through
172+ it. We can set them up follows:
173+
174+ 1 . [ ` pip install trustme-cli ` ] ( https://github.com/sethmlarson/trustme-cli/ ) .
175+ 2 . ` trustme-cli -i example.org www.example.org ` , assuming you want to test
176+ connecting to that domain, this will create three files: ` server.pem ` ,
177+ ` server.key ` and ` client.pem ` .
178+ 3 . ` mitmproxy ` requires a PEM file that includes the private key and the
179+ certificate so we need to concatenate them:
180+ ` cat server.key server.pem > server.withkey.pem ` .
181+ 4 . Start the proxy server ` mitmproxy --certs server.withkey.pem ` , or use the
182+ [ other mitmproxy commands] ( https://docs.mitmproxy.org/stable/ ) with different
183+ UI options.
184+
185+ At this point the server is ready to start serving requests, you'll need to
186+ configure HTTPX as described in the
187+ [ proxy section] ( https://www.python-httpx.org/advanced/#http-proxying ) and
188+ the [ SSL certificates section] ( https://www.python-httpx.org/advanced/#ssl-certificates ) ,
189+ this is where our previously generated ` client.pem ` comes in:
190+
191+ ```
192+ import httpx
193+
194+ proxies = {"all": "http://127.0.0.1:8080/"}
195+
196+ with httpx.Client(proxies=proxies, verify="/path/to/client.pem") as client:
197+ response = client.get("https://example.org")
198+ print(response.status_code) # should print 200
199+ ```
200+
201+ Note, however, that HTTPS requests will only succeed to the host specified
202+ in the SSL/TLS certificate we generated, HTTPS requests to other hosts will
203+ raise an error like:
204+
205+ ```
206+ ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate
207+ verify failed: Hostname mismatch, certificate is not valid for
208+ 'duckduckgo.com'. (_ssl.c:1108)
209+ ```
210+
211+ If you want to make requests to more hosts you'll need to regenerate the
212+ certificates and include all the hosts you intend to connect to in the
213+ seconds step, i.e.
214+
215+ ` trustme-cli -i example.org www.example.org duckduckgo.com www.duckduckgo.com `
0 commit comments