Open cathaychris opened 3 years ago
Update: this happens on CPython as well as micropython ports. I have tracked it down to the following and propose a fix, although I do not yet fully understand whether this is a bug or partially intentional.
The problem arises in _onDataSent
in httpResponse
, specifically:
if self._keepAlive :
self._request._waitForRecvRequest()
where in _waitForRecvRequest()
a new Response
object is created (attached to the same Request
object) and old headers are flushed. This could be OK, except that in the httpResponse
function Return
(for example, although this appears in many places) the last line checks self._hdrSent = True
, where self
is the original Response
object.
However, when the _routeRequest
checks if headers have been sent later,
if not self._response.HeadersSent :
self._mws2.Log( 'No response was sent from route %s.'
% self._routeResult,
self._mws2.WARNING )
self._response.ReturnNotImplemented()
it pulls the new response object, on which the _hdrSet
property has not been set.
This is why different memory addresses were observed above.
This can be fixed by, for example, replacing
self._hdrSent = True
with
self.Request.Response._hdrSent = True
(in multiple locations) which enforces that the most recent Response object is used. A cleaner way would perhaps be to attach the _hdrSent
property to the Request
object, since this is less mutable, and the code is written such that the response object is highly subject to change.
I also have this issue. Althought the client end receives its data, it also seems to cause a 501 error for following request from certain browsers (actually probably if the browser is reusing the connection I think)
I went for the simple and stupid fix, and commented out the check in _routeRequest() completely, and it now no longer gives the error nor causes an issue with subsequent requests.
If there is a better (less hacky) fix then I'm in the market....
However, the project in general is fab and works well for my test setup! (PyCom FiPy test stub for as yet unavailable hw!)
thanks Brian
I have the same issue on ESP32 with micropython. Besides this, very enjoyable project! Thank you
MWS2-DEBUG> From 192.168.4.2:50851 POST /processor >> [200] OK MWS2-WARNING> No response was sent from route processor. MWS2-DEBUG> From 192.168.4.2:50851 >> [501] Not Implemented
Same here with the latest code as of 2021-05-17.
The error
is raised for any route response, for example from the
/test-post
route in the example server, which callsrequest.Response.ReturnOk
. But this also applies to anything that eventually callsrequest.Response.Return
.It can be reproduced by running the example server from
main.py
and navigating to http://localhost/test-post, and observing the server logs.This supposedly arises from the absence of headers, but
ReturnOk
generates and transmits headers itself. My browser receives the headers and the content OK. Furthermore, if I add a response-finished callback set underrequest.Response.OnSent
, I can confirm the response is completed successfully (including headers).Indeed, querying
request.Response._hdrSent
returnsFalse
at any point, andrequest.Response._headers
also returns{}
, including after a successfully finished response (querying from within the@WebRoute
callback function).I can remove the error by duplicating the
Return
call:What is especially odd is, if I query the
HttpResponse
object before and after sending a responsethe response object has been recreated at a new spot in memory. This does not make sense to me, since the
HttpResponse
object is instantiated as part of theHttpRequest
object, which in fact does not change throughout the handler.My connection is currently quite slow, maybe this could be caused by a timeout issue? But based on the observations above, it seems more fundamental.