Skip to content

Interceptor body-size measurement: aiohttp json=, httpx streaming, Content-Length only #8

@AndresL230

Description

@AndresL230

Summary

Three related body-sizing issues:

1. aiohttp json= and FormData report 0 bytes

recost/_interceptor.py:317-325 checks only the data= kwarg. The most common aiohttp POST patterns (session.post(url, json={...}), session.post(url, data=FormData(...)), async-iterable bodies, BytesIO) all fall through and report 0.

2. httpx streaming body silently materialized

_interceptor.py:198-201, 244-247 accesses request.content to compute body size. For ordinary requests built via client methods, content is bytes — fine. For users passing a custom streaming body (httpx.Request("POST", url, content=async_iterator)), accessing content reads and buffers the entire iterator. A large upload silently OOMs the process.

3. Response body size derived from Content-Length only

Chunked / streaming responses (LLM SSE streams) don't set the header; they always report response_bytes=0. The README's "response body size (bytes)" promise is partially false for streams.

Fix

  • For aiohttp: when json= is present, JSON-serialize and measure; for FormData, query its _size; for unknown body types, leave at 0 but document.
  • For httpx: isinstance(request.content, bytes) check before reading. Non-bytes → skip size measurement.
  • For responses: document the streaming caveat in README; optionally tee non-streaming response bodies.

Files

  • recost/_interceptor.py
  • README.md
  • tests/test_interceptor.py

Priority

P1 — undercounts bytes for the most common modern HTTP patterns; OOM risk on streaming uploads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Should fix before next releasebugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions