41 lines
1.6 KiB
Python
41 lines
1.6 KiB
Python
from fastapi import FastAPI, Request, Response
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
from starlette.types import ASGIApp
|
|
|
|
class TextPlainMiddleware(BaseHTTPMiddleware):
|
|
def __init__(self, app: ASGIApp):
|
|
super().__init__(app)
|
|
|
|
async def dispatch(self, request: Request, call_next):
|
|
# Check if content type is text/*
|
|
content_type = request.headers.get("content-type", "")
|
|
|
|
if content_type and content_type.startswith("text/"):
|
|
# Store the original receive method
|
|
original_receive = request._receive
|
|
|
|
# Create a modified receive that will store the body
|
|
body = b""
|
|
async def receive():
|
|
nonlocal body
|
|
message = await original_receive()
|
|
if message["type"] == "http.request":
|
|
body += message.get("body", b"")
|
|
# Update body to be empty so it won't be processed by other middleware
|
|
# message["body"] = b""
|
|
return message
|
|
|
|
# Replace the receive method
|
|
request._receive = receive
|
|
|
|
# Process the request
|
|
response = await call_next(request)
|
|
|
|
# After the response is generated, we can access the full body
|
|
# and attach it to the request state for the route to access
|
|
request.state.text_body = body.decode("utf-8")
|
|
|
|
return response
|
|
else:
|
|
# For other content types, proceed as normal
|
|
return await call_next(request) |