You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `aiohttp <https://docs.aiohttp.org/en/stable/index.html>`_ library is an async HTTP client/server framework for Python. This page describes how to use aiohttp with proxies and how to interact with proxy headers.
4
+
The `aiohttp <https://docs.aiohttp.org/en/stable/index.html>`_ library is an async HTTP client/server framework for Python. This page describes how to use aiohttp with proxies and how to send and receive custom proxy headers.
5
+
6
+
Getting Started
7
+
---------------
8
+
9
+
This section shows you how to quickly get up and running with proxy headers in aiohttp.
10
+
11
+
**Prerequisites:**
12
+
13
+
1. Install the packages:
14
+
15
+
.. code-block:: bash
16
+
17
+
pip install python-proxy-headers aiohttp
18
+
19
+
2. Import the module:
20
+
21
+
.. code-block:: python
22
+
23
+
from python_proxy_headers import aiohttp_proxy
24
+
25
+
**Quick Example - Send and Receive Proxy Headers:**
26
+
27
+
.. code-block:: python
28
+
29
+
import asyncio
30
+
from python_proxy_headers import aiohttp_proxy
31
+
32
+
asyncdefmain():
33
+
asyncwith aiohttp_proxy.ProxyClientSession() as session:
34
+
asyncwith session.get(
35
+
'https://api.ipify.org?format=json',
36
+
proxy='http://PROXYHOST:PORT',
37
+
proxy_headers={'X-ProxyMesh-Country': 'US'}
38
+
) as response:
39
+
# Access the response data
40
+
data =await response.json()
41
+
print(data) # {"ip": "..."}
42
+
43
+
# Access proxy response headers
44
+
print(response.headers.get('X-ProxyMesh-IP'))
45
+
46
+
asyncio.run(main())
47
+
48
+
That's it! The ``ProxyClientSession`` handles sending your custom headers to the proxy and makes proxy response headers available in the response.
5
49
6
50
Using Proxies with aiohttp
7
51
---------------------------
8
52
9
53
aiohttp provides built-in support for proxies through the ``proxy`` parameter in request methods. You can specify a proxy URL for each request.
10
54
11
-
Basic Proxy Usage
12
-
~~~~~~~~~~~~~~~~~
55
+
Basic Proxy Usage (Standard aiohttp)
56
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13
57
14
-
To use a proxy with aiohttp, you can pass the ``proxy`` parameter to any request method:
proxy_headers={'X-ProxyMesh-Country': 'US'}) as r:
38
-
text =await r.text()
160
+
import asyncio
161
+
162
+
asyncdefmain():
163
+
asyncwith aiohttp.ClientSession() as session:
164
+
asyncwith session.get(
165
+
'https://api.ipify.org?format=json',
166
+
proxy='http://PROXYHOST:PORT',
167
+
proxy_headers={'X-ProxyMesh-Country': 'US'}
168
+
) as response:
169
+
text =await response.text()
170
+
171
+
asyncio.run(main())
39
172
40
173
The ``proxy_headers`` parameter allows you to send custom headers to the proxy server. This is useful for controlling proxy behavior, such as selecting a specific country or IP address.
41
174
42
175
Receiving Proxy Response Headers
43
176
---------------------------------
44
177
45
-
However, if you want to get proxy response headers, you should use our extension module ``python_proxy_headers.aiohttp_proxy``:
178
+
Standard aiohttp does not expose proxy response headers from the CONNECT request. To get proxy response headers, use our extension module ``python_proxy_headers.aiohttp_proxy``:
46
179
47
180
.. code-block:: python
48
181
182
+
import asyncio
49
183
from python_proxy_headers import aiohttp_proxy
50
-
asyncwith aiohttp_proxy.ProxyClientSession() as session:
proxy_headers={'X-ProxyMesh-Country': 'US'}) as r:
54
-
text =await r.text()
55
-
proxy_ip = r.headers['X-ProxyMesh-IP']
184
+
185
+
asyncdefmain():
186
+
asyncwith aiohttp_proxy.ProxyClientSession() as session:
187
+
asyncwith session.get(
188
+
'https://api.ipify.org?format=json',
189
+
proxy='http://PROXYHOST:PORT',
190
+
proxy_headers={'X-ProxyMesh-Country': 'US'}
191
+
) as response:
192
+
data =await response.json()
193
+
194
+
# Proxy response headers are now available
195
+
proxy_ip = response.headers.get('X-ProxyMesh-IP')
196
+
print(f"Request was made through: {proxy_ip}")
197
+
198
+
asyncio.run(main())
56
199
57
200
The ``ProxyClientSession`` extends the standard ``ClientSession`` to make proxy response headers available in the response headers. This allows you to access information from the proxy server, such as the IP address that was assigned to your request.
58
201
@@ -68,11 +211,13 @@ Here's a complete example showing how to use aiohttp with proxy headers:
68
211
69
212
asyncdefmain():
70
213
asyncwith aiohttp_proxy.ProxyClientSession() as session:
proxy_headers={'X-ProxyMesh-Country': 'US'}) as r:
74
-
data =await r.json()
75
-
proxy_ip = r.headers.get('X-ProxyMesh-IP')
214
+
asyncwith session.get(
215
+
'https://api.ipify.org?format=json',
216
+
proxy='http://PROXYHOST:PORT',
217
+
proxy_headers={'X-ProxyMesh-Country': 'US'}
218
+
) as response:
219
+
data =await response.json()
220
+
proxy_ip = response.headers.get('X-ProxyMesh-IP')
76
221
print(f"Your IP: {data['ip']}")
77
222
print(f"Proxy IP: {proxy_ip}")
78
223
@@ -101,3 +246,74 @@ The ``ProxyClientSession`` works just like the standard ``ClientSession`` and su
101
246
102
247
All standard aiohttp request methods are supported: ``get``, ``post``, ``put``, ``delete``, ``patch``, ``head``, and ``options``.
103
248
249
+
Extension Classes
250
+
-----------------
251
+
252
+
The ``python_proxy_headers.aiohttp_proxy`` module provides several extension classes that work together to capture and expose proxy response headers. These classes extend aiohttp's internal classes.
253
+
254
+
ProxyClientSession
255
+
~~~~~~~~~~~~~~~~~~
256
+
257
+
The main entry point for using proxy headers with aiohttp. This class extends ``aiohttp.ClientSession`` and automatically configures the session to use the other extension classes.
258
+
259
+
.. code-block:: python
260
+
261
+
from python_proxy_headers.aiohttp_proxy import ProxyClientSession
262
+
263
+
asyncwith ProxyClientSession() as session:
264
+
asyncwith session.get('https://example.com', proxy='http://PROXYHOST:PORT') as r:
265
+
proxy_ip = r.headers.get('X-ProxyMesh-IP')
266
+
267
+
The ``ProxyClientSession`` constructor accepts all the same arguments as ``aiohttp.ClientSession``, and automatically sets:
268
+
269
+
* ``connector`` to ``ProxyTCPConnector()``
270
+
* ``response_class`` to ``ProxyClientResponse``
271
+
* ``request_class`` to ``ProxyClientRequest``
272
+
273
+
ProxyTCPConnector
274
+
~~~~~~~~~~~~~~~~~
275
+
276
+
Extends ``aiohttp.TCPConnector`` to capture proxy response headers during HTTPS tunnel establishment. This class overrides the ``_create_proxy_connection`` method to:
277
+
278
+
1. Send the CONNECT request with custom proxy headers
279
+
2. Capture the proxy's response headers from the CONNECT response
280
+
3. Store them on the protocol object for later retrieval
281
+
282
+
When establishing an HTTPS connection through a proxy, the connector:
283
+
284
+
* Creates a CONNECT request to the proxy server
285
+
* Includes any custom proxy headers you've specified
286
+
* Captures the proxy's response headers (e.g., ``X-ProxyMesh-IP``)
287
+
* Stores them so they can be merged into the final response
288
+
289
+
You typically don't need to use this class directly - it's automatically configured when using ``ProxyClientSession``.
290
+
291
+
ProxyClientRequest
292
+
~~~~~~~~~~~~~~~~~~
293
+
294
+
Extends ``aiohttp.ClientRequest`` to transfer proxy headers from the connection protocol to the response object. This class overrides the ``send`` method to check if the connection's protocol has captured proxy headers and attaches them to the response.
295
+
296
+
This class is used internally by ``ProxyClientSession`` and typically doesn't need to be used directly.
297
+
298
+
ProxyClientResponse
299
+
~~~~~~~~~~~~~~~~~~~
300
+
301
+
Extends ``aiohttp.ClientResponse`` to merge proxy response headers into the response's headers property. This class overrides the ``headers`` property to:
302
+
303
+
1. Check if proxy headers were captured during tunnel establishment
304
+
2. If present, merge them with the target server's response headers
305
+
3. Return a combined ``CIMultiDictProxy`` containing both sets of headers
306
+
307
+
This allows you to access proxy response headers (like ``X-ProxyMesh-IP``) directly from the response object's ``headers`` property, alongside the target server's response headers.
308
+
309
+
How It Works
310
+
~~~~~~~~~~~~
311
+
312
+
The extension classes work together in the following flow:
313
+
314
+
1. **ProxyClientSession** creates a session configured with all the extension classes
315
+
2. **ProxyTCPConnector** intercepts the CONNECT request/response during tunnel establishment and captures proxy headers
316
+
3. **ProxyClientRequest** transfers the captured headers from the protocol to the response object
317
+
4. **ProxyClientResponse** merges the proxy headers into the response's ``headers`` property
318
+
319
+
This allows proxy response headers to be transparently available in your application without any special handling.
0 commit comments