vpndetection-fastapi 2.1.2__tar.gz → 2.1.3__tar.gz

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.
@@ -2,6 +2,12 @@
2
2
 
3
3
  What each release changed for you, newest first. Each line is a commit's summary, linked to its full description and diff. Releases before 2.0.5 are described by their release commits.
4
4
 
5
+ ## 2.1.3 - 2026-10-10
6
+
7
+ ### Fixes
8
+
9
+ - Require vpndetection 5.7.1: the spec re-pinned to 2026.10.09 ([`62563b2`](https://github.com/vpndetection-io/sdk-python-fastapi/commit/62563b2ec2b31e6b317d836c229f939bb9f0ec30))
10
+
5
11
  ## 2.1.2 - 2026-10-06
6
12
 
7
13
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vpndetection-fastapi
3
- Version: 2.1.2
3
+ Version: 2.1.3
4
4
  Summary: Official FastAPI and Starlette middleware for the VPNDetection API. Detect VPNs, proxies, Tor, hosting and CDN visitors on every request.
5
5
  Project-URL: Homepage, https://vpndetection.io
6
6
  Project-URL: Source, https://github.com/vpndetection-io/sdk-python-fastapi
@@ -20,7 +20,7 @@ Classifier: Topic :: Security
20
20
  Classifier: Typing :: Typed
21
21
  Requires-Python: >=3.11
22
22
  Requires-Dist: starlette>=0.37
23
- Requires-Dist: vpndetection<6,>=5.7.0
23
+ Requires-Dist: vpndetection<6,>=5.7.1
24
24
  Provides-Extra: dev
25
25
  Requires-Dist: fastapi>=0.115; extra == 'dev'
26
26
  Requires-Dist: mypy>=1.11; extra == 'dev'
@@ -112,7 +112,7 @@ A refused request gets an `HTTPException`, `403` with `{"detail": "access denied
112
112
 
113
113
  This is the setting that decides whether any of the above works, and it is the one thing only you can get right.
114
114
 
115
- By default the middleware uses `request.client.host`, which is the socket peer unless the server was started with proxy-header support. Behind a load balancer without it, every visitor looks like the load balancer — a datacenter address, so a hosting rule would block all of them. Starting uvicorn with `--proxy-headers --forwarded-allow-ips=<your proxy>` is the server's own answer, and the one that knows your topology.
115
+ By default the middleware uses `request.client.host`. uvicorn, and `fastapi run` with it, reads proxy headers by default, but only from a peer that `--forwarded-allow-ips` trusts, and that defaults to `127.0.0.1,::1` (or `$FORWARDED_ALLOW_IPS`). So behind a proxy on the same machine, the visitor's address arrives with no setup. Behind one anywhere else, such as nginx in its own container or a load balancer in a VPC, every visitor looks like the proxy. That address is usually a private one, which the middleware answers locally: nobody is flagged, nothing is blocked, and the private-address warning below is the only sign. Name your proxy, by its address or its subnet: `--forwarded-allow-ips=172.28.5.0/28`. gunicorn's own `--forwarded-allow-ips` works the same way. Never pass `*`. It trusts every peer, so the left-most `X-Forwarded-For` entry wins, and that is whatever the visitor sent: someone on a VPN who sends `X-Forwarded-For: 1.1.1.1` is looked up as `1.1.1.1`.
116
116
 
117
117
  For an edge that writes the address into its own header, name the header:
118
118
 
@@ -82,7 +82,7 @@ A refused request gets an `HTTPException`, `403` with `{"detail": "access denied
82
82
 
83
83
  This is the setting that decides whether any of the above works, and it is the one thing only you can get right.
84
84
 
85
- By default the middleware uses `request.client.host`, which is the socket peer unless the server was started with proxy-header support. Behind a load balancer without it, every visitor looks like the load balancer — a datacenter address, so a hosting rule would block all of them. Starting uvicorn with `--proxy-headers --forwarded-allow-ips=<your proxy>` is the server's own answer, and the one that knows your topology.
85
+ By default the middleware uses `request.client.host`. uvicorn, and `fastapi run` with it, reads proxy headers by default, but only from a peer that `--forwarded-allow-ips` trusts, and that defaults to `127.0.0.1,::1` (or `$FORWARDED_ALLOW_IPS`). So behind a proxy on the same machine, the visitor's address arrives with no setup. Behind one anywhere else, such as nginx in its own container or a load balancer in a VPC, every visitor looks like the proxy. That address is usually a private one, which the middleware answers locally: nobody is flagged, nothing is blocked, and the private-address warning below is the only sign. Name your proxy, by its address or its subnet: `--forwarded-allow-ips=172.28.5.0/28`. gunicorn's own `--forwarded-allow-ips` works the same way. Never pass `*`. It trusts every peer, so the left-most `X-Forwarded-For` entry wins, and that is whatever the visitor sent: someone on a VPN who sends `X-Forwarded-For: 1.1.1.1` is looked up as `1.1.1.1`.
86
86
 
87
87
  For an edge that writes the address into its own header, name the header:
88
88
 
@@ -24,7 +24,7 @@ classifiers = [
24
24
  "Topic :: Security",
25
25
  "Typing :: Typed",
26
26
  ]
27
- dependencies = ["vpndetection>=5.7.0,<6", "starlette>=0.37"]
27
+ dependencies = ["vpndetection>=5.7.1,<6", "starlette>=0.37"]
28
28
 
29
29
  [project.urls]
30
30
  Homepage = "https://vpndetection.io"
@@ -45,7 +45,7 @@ __all__ = [
45
45
  "xff_ip_selector",
46
46
  ]
47
47
 
48
- __version__ = "2.1.2"
48
+ __version__ = "2.1.3"
49
49
 
50
50
  # Set on a request ``skip`` claimed, so block_if can tell it from one the middleware
51
51
  # never saw.
@@ -58,13 +58,14 @@ _SELECTORS: Selectors[Request] = bind_selectors(
58
58
  )
59
59
  )
60
60
 
61
- #: ``request.client.host``, which is the socket peer unless the app was started with
62
- #: uvicorn's ``--proxy-headers``.
61
+ #: ``request.client.host``. uvicorn reads proxy headers into it by default, but only
62
+ #: from a peer ``--forwarded-allow-ips`` trusts, which defaults to ``127.0.0.1,::1``.
63
63
  #:
64
- #: Behind a load balancer without it, every visitor looks like the load balancer - a
65
- #: datacenter address a hosting rule would block them all for. If you are behind one,
66
- #: pass ``--proxy-headers --forwarded-allow-ips=<your proxy>`` (the server's own answer,
67
- #: and the one that knows your topology) or use :func:`header_ip_selector`.
64
+ #: Behind a proxy anywhere else, every visitor looks like the proxy, usually a private
65
+ #: address that is answered locally, so nobody is flagged and the private-address
66
+ #: warning is the only sign. Pass ``--forwarded-allow-ips=<your proxy's address or
67
+ #: subnet>``, never ``*``, which takes the left-most ``X-Forwarded-For`` entry a visitor
68
+ #: can forge, or use :func:`header_ip_selector`.
68
69
  default_ip_selector: IpSelector[Request] = _SELECTORS.default
69
70
 
70
71
  #: An address from ``X-Forwarded-For``.