Consuming the request body multiple times #1933
antonpirker
started this conversation in
General
Replies: 3 comments 18 replies
-
Some context: This leads to this problem in the Sentry Starlette integration: getsentry/sentry-python#1675 |
Beta Was this translation helpful? Give feedback.
5 replies
-
I suppose one could write some middleware that runs before all other
middleware and saved a copy?
I'm brand new to Starlette/FastAPI so I have no idea how hard that is to do
but I have to assume it would not be that complicated. Any pointers? I'm
sure others would like to use it as well.
Thanks.
…On Fri, Aug 18, 2023, 13:45 Adrian Garcia Badaracco < ***@***.***> wrote:
There is no reason why this *must* work in any specific way. If we just
stored the body in case someone wanted it lasted we'd end up doubling the
memory usage for all users (most of which don't need that feature). The
reason this is not the case with .body() is that we can return a
reference to the exact same bytes. With .form() the bytes get parsed and
transformed, so we'd be keeping two copies around.
—
Reply to this email directly, view it on GitHub
<#1933 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AG27XGLRMON56YH7NZQJAS3XV5PVFANCNFSM6AAAAAARVC2FJY>
.
You are receiving this because you commented.Message ID:
***@***.***>
--
____________________________
The information included in this
e-mail and any file attached to it, are privileged and confidential and is
intended only for use of the addressee. If you are not the intended
recipient or the employee or agent responsible for delivering the message
to the intended recipient, or you have received this communication in
error, please be aware that any dissemination, distribution or duplication
of this communication is strictly prohibited. Please notify us immediately
and destroy the original without reading it.
Your personal data will be
processed by SECRET SOURCE TECHNOLOGY, S. L., address at C/ Bravo Murillo,
34, 35003, Las Palmas de G. C., for the purpose of managing communications
made by e-mail due to the services provided, commercial information or
activities carried out by the Responsible.
You can exercise your rights
of access, rectification, deletion, restriction of processing or
portability by writing to the file manager SECRET SOURCE TECHNOLOGY, S. L.,
C/ Bravo Murillo, 34, 35003, Las Palmas de G. C. You have the right to
lodge a complaint at the AEPD (www.aepd.es <http://www.aepd.es>).
You can
consult/request more information on data protection at
***@***.*** ***@***.***>.
|
Beta Was this translation helpful? Give feedback.
7 replies
-
Is there already a solution here? Forgive me for using form(), body(), json() together in my middleware. In version 0.32, I have a form-data request, and if I call them after call(request), the stream is already consumed, and if I call them before, then call(request) is subject to the empty body(). |
Beta Was this translation helpful? Give feedback.
6 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello!
There are three high level functions to read the request body:
Request.json()
,Request.form()
andRequest.body()
:https://github.com/encode/starlette/blob/master/starlette/requests.py#L231-L266
All of them use the function
Request.stream()
to read the actual data:https://github.com/encode/starlette/blob/master/starlette/requests.py#L208-L229
All of them cache the request data in a variable called
_json
,_form
, and_body
respectively.Because of this I can call either of
.json()
,.form()
or.body()
multiple times and it works because the stream is only consumed once and from subsequent calls served from the cache.It is also possible to call
.json()
and then.body()
because.json()
uses internally.body()
to get the data (and therefore the second call to.body()
gets the cached data from_body
)But if I call
.form()
and then.body()
I get anRuntimeError: Stream consumed
because.form()
is calling.stream()
directly (and not.body()
) and saving the request data to_form
.But
.stream()
is only checking if there is a_body
and, if yes, returning this, but in this case there is no_body
so it is trying to read the stream once again, which is not possible and leads to the RuntimeError.Question:
Is this by design or just a coincidence?
Would it make sense:
A) in
stream()
to also check for the existence of_form
rather then just_body
? (having a secondif
statement similar to this one: https://github.com/encode/starlette/blob/master/starlette/requests.py#L209-L212)B) or call
.body()
inside of.form()
so the request data is cached in_body
?Beta Was this translation helpful? Give feedback.
All reactions