"No response was sent from route" error always raised
cathaychris opened this issue · 4 comments
The error
MWS2-DEBUG> From 192.168.86.48:61468 GET /test-post >> [200] OK
MWS2-WARNING> No response was sent from route TestPost1/2.
MWS2-DEBUG> From 192.168.86.48:61539 >> [501] Not Implemented
is raised for any route response, for example from the /test-post
route in the example server, which calls request.Response.ReturnOk
. But this also applies to anything that eventually calls request.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 under request.Response.OnSent
, I can confirm the response is completed successfully (including headers).
Indeed, querying request.Response._hdrSent
returns False
at any point, and request.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:
request.Response.ReturnOk(content)
request.Response.ReturnOk(content)
What is especially odd is, if I query the HttpResponse
object before and after sending a response
@WebRoute(GET, '/test', name="test")
def _handler(server, request):
print('request:', request)
print('response:', request.Response)
request.Response.ReturnOkJSON('test')
print('request:', request)
print('response:', request.Response) # different memory address than before!
the 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 the HttpRequest
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.
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.