python-ipware 2.0.2__py3-none-any.whl → 2.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- __version__ = "2.0.2"
1
+ __version__ = "2.0.4"
@@ -28,6 +28,7 @@ class IpWareMeta:
28
28
  "HTTP_X_CLUSTER_CLIENT_IP", # Rackspace LB and Riverbed Stingray
29
29
  "HTTP_FORWARDED_FOR", # RFC 7239
30
30
  "HTTP_FORWARDED", # RFC 7239
31
+ "HTTP_CF_CONNECTING_IP", # CloudFlare
31
32
  "X-CLIENT-IP", # Microsoft Azure
32
33
  "X-REAL-IP", # NGINX
33
34
  "X-CLUSTER-CLIENT-IP", # Rackspace Cloud Load Balancers
@@ -143,12 +144,9 @@ class IpWareProxy:
143
144
 
144
145
  def __init__(
145
146
  self,
146
- proxy_count: int = 0,
147
+ proxy_count: Optional[int] = None,
147
148
  proxy_list: Optional[List[str]] = None,
148
149
  ) -> None:
149
- if proxy_count is None or proxy_count < 0:
150
- raise ValueError("proxy_count must be a positive integer")
151
-
152
150
  self.proxy_count = proxy_count
153
151
  self.proxy_list = self._is_valid_proxy_trusted_list(proxy_list or [])
154
152
 
@@ -171,15 +169,14 @@ class IpWareProxy:
171
169
  """
172
170
  Checks if the proxy count is valid
173
171
  @param ip_list: list of ip addresses
174
- @param strict: if True, we must have exactly proxy_count proxies
172
+ @param strict: if True, we must have exactly proxy_count proxies, including `0` proxies
175
173
  @return: True if the proxy count is valid, False otherwise
176
174
  """
177
- if self.proxy_count < 1:
175
+ # No proxy count check is required
176
+ if self.proxy_count is None:
178
177
  return True
179
178
 
180
179
  ip_count: int = len(ip_list)
181
- if ip_count < 1:
182
- return False
183
180
 
184
181
  if strict:
185
182
  # our first proxy takes the last ip address and treats it as client ip
@@ -220,10 +217,6 @@ class IpWareProxy:
220
217
  if not str(value).startswith(self.proxy_list[index]):
221
218
  return False
222
219
 
223
- # now all we need is to return the first ip in the list that is not in the trusted proxy list
224
- # best_client_ip_index = proxy_list_count + 1
225
- # best_client_ip = ip_list[-best_client_ip_index]
226
-
227
220
  return True
228
221
 
229
222
 
@@ -236,11 +229,11 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
236
229
  self,
237
230
  precedence: Optional[Tuple[str, ...]] = None,
238
231
  leftmost: bool = True,
239
- proxy_count: int = 0,
232
+ proxy_count: Optional[int] = None,
240
233
  proxy_list: Optional[List[str]] = None,
241
234
  ) -> None:
242
235
  IpWareMeta.__init__(self, precedence, leftmost)
243
- IpWareProxy.__init__(self, proxy_count or 0, proxy_list or [])
236
+ IpWareProxy.__init__(self, proxy_count, proxy_list)
244
237
 
245
238
  def get_meta_value(self, meta: Dict[str, str], key: str) -> str:
246
239
  """
@@ -256,7 +249,13 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
256
249
  Given a list of keys, it returns a list of cleaned up values
257
250
  @return: a list of values
258
251
  """
259
- return [self.get_meta_value(meta, key) for key in self.precedence]
252
+ meta_list: List[str] = []
253
+ for key in self.precedence:
254
+ value = self.get_meta_value(meta, key).strip()
255
+ if value:
256
+ meta_list.append(value)
257
+
258
+ return meta_list
260
259
 
261
260
  def get_client_ip(
262
261
  self,
@@ -271,8 +270,6 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
271
270
  private_list: List[OptionalIpAddressType] = []
272
271
 
273
272
  for ip_str in self.get_meta_values(meta):
274
- if not ip_str:
275
- continue
276
273
 
277
274
  ip_list = self.get_ips_from_string(ip_str)
278
275
  if not ip_list:
@@ -336,7 +333,11 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
336
333
  return best_client_ip, True
337
334
 
338
335
  # the incoming ips match our proxy count
339
- if self.proxy_count > 0 and proxy_count_validated:
336
+ if (
337
+ self.proxy_count is not None
338
+ and self.proxy_count > 0
339
+ and proxy_count_validated
340
+ ):
340
341
  best_client_ip_index = self.proxy_count + 1
341
342
  best_client_ip = ip_list[-best_client_ip_index]
342
343
  return best_client_ip, True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-ipware
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: A Python package to retrieve user's IP address
5
5
  Author-email: Val Neekman <info@neekware.com>
6
6
  License: MIT
@@ -134,6 +134,7 @@ request_headers_precedence_order = (
134
134
  "HTTP_X_CLUSTER_CLIENT_IP", # Rackspace LB and Riverbed Stingray
135
135
  "HTTP_FORWARDED_FOR", # RFC 7239
136
136
  "HTTP_FORWARDED", # RFC 7239
137
+ "HTTP_CF_CONNECTING_IP", # CloudFlare
137
138
  "X-CLIENT-IP", # Microsoft Azure
138
139
  "X-REAL-IP", # NGINX
139
140
  "X-CLUSTER-CLIENT-IP", # Rackspace Cloud Load Balancers
@@ -215,23 +216,41 @@ If your python server is behind a `known` number of proxies, but you deploy on m
215
216
  You can customize the proxy count by providing your `proxy_count` during initialization when calling `IpWare(proxy_count=2)`.
216
217
 
217
218
  ```python
218
- # In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.
219
219
  from python_ipware import IpWare
220
220
 
221
- # enforce proxy count
222
- ipw = IpWare(proxy_count=1)
221
+ # Enforce proxy count
222
+ # proxy_count=0 is valid
223
+ # proxy_count=None to disable proxy_count check
224
+ ipw = IpWare(proxy_count=2)
223
225
 
224
- # enforce proxy count and trusted proxies
225
- ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
226
+ # Example usage in non-strict mode:
227
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
228
+ # At least `proxy_count` number of proxies
229
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
226
230
 
231
+ # Example usage in strict mode:
232
+ # X-Forwarded-For format: <client>, <proxy1>, <proxy2>
233
+ # Exact `proxy_count` number of proxies
234
+ ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
235
+ ```
227
236
 
228
- # usage: non-strict mode (X-Forwarded-For: <fake>, <client>, <proxy1>, <proxy2>)
229
- # total number of ip addresses are greater than the total count
230
- ip, trusted_route = ipw.get_client_ip(meta=request.META)
237
+ ### Proxy Count & Trusted Proxy List Combo
238
+ In this example, we utilize the total number of proxies as a method to filter out unwanted requests while verifying the trust proxies.
231
239
 
240
+ ```python
241
+ from python_ipware import IpWare
232
242
 
233
- # usage: strict mode (X-Forwarded-For: <client>, <proxy1>, <proxy2>)
234
- # total number of ip addresses are exactly equal to client ip + proxy_count
243
+ # Enforce both proxy count and trusted proxies
244
+ ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
245
+
246
+ # Example usage in non-strict mode:
247
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
248
+ # At least `proxy_count` number of proxies
249
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
250
+
251
+ # Example usage in strict mode:
252
+ # X-Forwarded-For format: <client>, <proxy1>
253
+ # Exact `proxy_count` number of proxies
235
254
  ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
236
255
  ```
237
256
 
@@ -0,0 +1,9 @@
1
+ python_ipware/__init__.py,sha256=TCZx4mt5Gxr2D_zNU6j0ynopdsAN_v4xeiTWz1OXSpY,87
2
+ python_ipware/__version__.py,sha256=ZOg41aCgKEuObK5WhegikXektFWPJaeZ-TMDh0Ke95M,22
3
+ python_ipware/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ python_ipware/python_ipware.py,sha256=sN3NeWWs96beGzI9x3YZ9ucYnMIZh1Q4fWOOIm2_P-s,11987
5
+ python_ipware-2.0.4.dist-info/LICENSE,sha256=MLpNxpqfTc4TLdcDk3x6k7Vz4lJGBNLV-SxQZlFMDU8,1103
6
+ python_ipware-2.0.4.dist-info/METADATA,sha256=-KqYlSwY52kwnnAMA7ym2A31L1yX8BffjMdZ3I32Wl0,15420
7
+ python_ipware-2.0.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
8
+ python_ipware-2.0.4.dist-info/top_level.txt,sha256=URE4dvjpReJtRHyQpJqoBow5EWt_RqVXFn85B9Tq5Xw,14
9
+ python_ipware-2.0.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- python_ipware/__init__.py,sha256=TCZx4mt5Gxr2D_zNU6j0ynopdsAN_v4xeiTWz1OXSpY,87
2
- python_ipware/__version__.py,sha256=tATvJM5shAzfspHYjdVwpV2w3-gDA119NlEYi5X2lFY,22
3
- python_ipware/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_ipware/python_ipware.py,sha256=V6yEmV2kBIrVqWf8eitUO1YFVIL18TdGdh37t2dHf9c,12068
5
- python_ipware-2.0.2.dist-info/LICENSE,sha256=MLpNxpqfTc4TLdcDk3x6k7Vz4lJGBNLV-SxQZlFMDU8,1103
6
- python_ipware-2.0.2.dist-info/METADATA,sha256=2H8IHP6sUsA-2I8IqbJDSOPVsBAKFRn-dBUD7ay_TP0,14814
7
- python_ipware-2.0.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
8
- python_ipware-2.0.2.dist-info/top_level.txt,sha256=URE4dvjpReJtRHyQpJqoBow5EWt_RqVXFn85B9Tq5Xw,14
9
- python_ipware-2.0.2.dist-info/RECORD,,