Skip to content

Commit 6acdc6e

Browse files
authored
Merge pull request #1200 from akrherz/fix_callable
🎨 Fix how ip_throttle gets called
2 parents 0e347b8 + 76f9a9d commit 6acdc6e

2 files changed

Lines changed: 19 additions & 11 deletions

File tree

src/pyiem/webutil.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -464,11 +464,18 @@ def _mcall(
464464
func: Callable,
465465
environ: dict,
466466
start_response: Callable,
467+
ip_throttle_secs: float | Callable,
467468
memcachekey: str | Callable | None,
468469
expire: int | Callable,
469470
content_type: str | Callable,
470471
):
471472
"""Call the function with memcachekey handling."""
473+
if ip_is_throttled(environ, ip_throttle_secs):
474+
start_response(
475+
"429 Too Many Requests",
476+
[("Content-type", "text/plain")],
477+
)
478+
return b"Too many requests from your IP address, slow down."
472479
if memcachekey is None:
473480
return func(environ, start_response)
474481
key = memcachekey if isinstance(memcachekey, str) else memcachekey(environ)
@@ -593,14 +600,6 @@ def _handle_exp(errormsg, routine=False, code=500):
593600
)
594601
return msg.encode("ascii", errors="replace")
595602

596-
if ip_is_throttled(environ, kwargs.get("ip_throttle_secs", 0)):
597-
start_response(
598-
"429 Too Many Requests",
599-
[("Content-type", "text/plain")],
600-
)
601-
yield b"Too many requests from your IP address, slow down."
602-
return
603-
604603
start_time = datetime.now(timezone.utc)
605604
status_code = 500
606605
try:
@@ -615,6 +614,7 @@ def _handle_exp(errormsg, routine=False, code=500):
615614
func,
616615
environ,
617616
start_response,
617+
kwargs.get("ip_throttle_secs", 0),
618618
kwargs.get("memcachekey"),
619619
kwargs.get("memcacheexpire", 3600),
620620
kwargs.get("content_type", "application/json"),

tests/test_webutil.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,25 @@ def test_xss_false_positive_ampersand():
5454
def test_ip_throttled_callable():
5555
"""Test that the ip throttle is callable."""
5656

57-
@iemapp(allowed_as_list=["q"], ip_throttle_secs=lambda _x: 0)
57+
class Schema(CGIModel):
58+
"""Test."""
59+
60+
q: Annotated[int, Field(description="A")] = 0
61+
62+
@iemapp(
63+
schema=Schema,
64+
ip_throttle_secs=lambda x: 0 if x["q"] < 0 else 10,
65+
)
5866
def application(_environ, start_response):
5967
"""Test."""
6068
start_response("200 OK", [("Content-type", "text/plain")])
6169
return f"{random.random()}"
6270

6371
eo = {"REMOTE_ADDR": "7.7.7.7"}
6472
c = Client(application)
65-
resp = c.get("/?q=1", environ_overrides=eo)
73+
resp = c.get("/?q=-1", environ_overrides=eo)
6674
assert resp.status_code == 200
67-
resp = c.get("/?q=1", environ_overrides=eo)
75+
resp = c.get("/?q=-1", environ_overrides=eo)
6876
assert resp.status_code == 200
6977

7078

0 commit comments

Comments
 (0)