Skip to content

Support AsyncIterable for request body (similar to httpx’s content param) #594

@likeaik

Description

@likeaik

Hi, thank you for your great work on curl_cffi!

I’m developing a high-concurrency reverse proxy service, and I noticed that currently curl_cffi does not support sending the request body as an AsyncIterable. This makes it difficult to implement streaming uploads, where the service needs to receive and upload data chunk by chunk (i.e., stream data while uploading).

In libraries like httpx, the content parameter can accept an AsyncIterable, which allows developers to stream the request body efficiently. It would be really helpful if curl_cffi could support this feature as well, so we could upload data as we receive it, rather than buffering the entire body before sending.

Feature request:

Add support for passing an AsyncIterable as the request body (similar to httpx’s content parameter).

This would enable efficient streaming uploads and better support for reverse proxy and other high-concurrency use cases.

Here is an example with httpx showing how this works:

import httpx
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse

app = FastAPI()

@app.post("/proxy")
async def proxy(request: Request):
    # Define an async generator to read and stream the incoming request body
    async def proxy_body():
        async for chunk in request.stream():
            yield chunk

    async with httpx.AsyncClient() as client:
        upstream_response = await client.post(
            "https://httpbin.org/post",
            content=proxy_body(),
            headers={key: value for key, value in request.headers.items() if key != "host"},
            timeout=None,
        )
        return StreamingResponse(
            upstream_response.aiter_raw(),
            status_code=upstream_response.status_code,
            headers=dict(upstream_response.headers),
        )

In the above example, async_content() is an async generator yielding data chunks, which httpx streams directly to the server as they are produced, without buffering the entire body.

Thank you for considering this feature!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions