Skip to content

Resonse body got cut off when containing binary image data using asgi protocol #564

Closed
@synodriver

Description

@synodriver

Hi,
When switching to unit, I found some imcompatible
Here is an example:

from pathlib import Path

from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()


@app.get("/")
async def _():
    f = open(str(Path(__file__).parent / "a.png"), "rb")  
    # It's just an example, actually it's generated in code instead of read from file
    return StreamingResponse(f, media_type="image/png")

Put a picture a.png in it's path, any picture is ok for that

My environment

The command unitd --version
got

unit version: 1.24.0
configured as ./configure --ld-opt=-fno-lto  --openssl

The version of fastapi and python

Python 3.8.5 
fastapi 0.63.0
uvicorn 0.14.0
hypercorn 0.9.2   

then try other asgi servers and unit to start a server using the same code

uvicorn main:app --port 9000
hypercorn main:app --bind 127.0.0.1:9001

the unit config

{
  "listeners": {
    "*:9002": {
      "pass": "applications/fastapi"
    }
  },
  "applications": {
    "fastapi": {
      "type": "python 3.8",
      "path": "path to app",
      "module": "main",
      "callable": "app"
    }
  }
}

Open http://127.0.0.1:9000 http://127.0.0.1:9001 http://127.0.0.1:9002 in browser and that's the difference

I did some research about this, found that unit may be mistake '\n' as the end of response.

I tested them using the folowing code

import requests

uvicorn_resp = requests.get("http://127.0.0.1:9000")
hypercorn_resp = requests.get("http://127.0.0.1:9001")
unit_resp = requests.get("http://127.0.0.1:9002")

print(f"uvicorn_resp length:{len(uvicorn_resp.content)}")
print(f"hypercorn_resp length:{len(hypercorn_resp.content)}")
print(f"unit_resp length:{len(unit_resp.content)}")

print(unit_resp.content)
assert chr(unit_resp.content[-1]) == "\n"

I got

uvicorn_resp length:142447
hypercorn_resp length:142447
unit_resp length:26
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\n'

It is obvious that response body of unit was cut off, while the other two asgi server doesn't.

Any Suggestion about that?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions