Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conformance/inflow-specs.lock.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"repository": "inflowpayai/inflow-specs",
"revision": "7737099308106a1cabaab57de1d621d881cce0e0"
"revision": "46f65400aa6e5b7a8f719a8378d5f36186e5c94d"
}
1 change: 1 addition & 0 deletions examples/tap_seller.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ async def catalog(request: Request) -> JSONResponse:
has_body = (
"content-length" in request.headers
or "transfer-encoding" in request.headers
or "content-digest" in request.headers
or bool(body)
)
# PUBLIC_ORIGIN is deployment configuration, never a client-supplied Forwarded header.
Expand Down
22 changes: 17 additions & 5 deletions tests/test_tap_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ async def test_http_example_accepts_real_signed_request_then_rejects_replay(
).status_code == 413


async def test_example_over_real_loopback_http() -> None:
@pytest.mark.parametrize("method,body", [("POST", b"{}"), ("GET", b"")])
async def test_example_over_real_loopback_http(method: str, body: bytes) -> None:
async with TapVerifier(key_resolver=Resolver(), clock=lambda: NOW) as verifier:
app = tap_seller.create_app(verifier, "https://public.example")
with socket.socket() as sock:
Expand All @@ -78,19 +79,30 @@ async def test_example_over_real_loopback_http() -> None:
await running
pytest.fail("Example server stopped before startup")
await asyncio.sleep(0.001)
request = signed(
body=b"{}", method="POST", url="https://public.example/api/catalog"
)
request = signed(body=body, method=method, url="https://public.example/api/catalog")
async with httpx.AsyncClient(
base_url=f"http://127.0.0.1:{sock.getsockname()[1]}"
) as client:
response = await client.post(
outbound = client.build_request(
method,
"/api/catalog",
content=request.body,
headers=cast(dict[str, str], request.headers),
)
if method == "GET":
assert "content-length" not in outbound.headers
assert "transfer-encoding" not in outbound.headers
tampered = client.build_request(
method,
"/api/catalog",
content=request.body,
headers={**cast(dict[str, str], request.headers), "content-digest": "bad"},
)
assert (await client.send(tampered)).status_code == 401
response = await client.send(outbound)
assert response.status_code == 200
assert response.json()["agent"]["keyid"] == "test-key"
assert (await client.send(outbound)).status_code == 401
assert (await client.get("/api/catalog")).status_code == 401
finally:
server.should_exit = True
Expand Down
Loading