Reputation: 1343
In order to test my client, I want to make some of the HTTP request sent by my client doesn't get any response.
For example, I want every request should have cookie topsession
, if not, no response.
class EchoHandler(tornado.web.RequestHandler):
def get(self):
if not self.get_cookie("topsession"):
###TODO
else:
self.write("0")
Upvotes: 2
Views: 1193
Reputation: 12587
The request's underlying connection can be closed explicitly
import tornado.ioloop
import tornado.web
from tornado.gen import coroutine
class MainHandler(tornado.web.RequestHandler):
@coroutine
def get(self):
self.request.connection.close()
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", MainHandler),
])
application.listen(8888)
tornado.ioloop.IOLoop.current().start()
And the test with curl:
curl http://localhost:8888/ -v
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.47.0
> Accept: */*
>
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server
The above code closes connection with FIN
-flow and leaves the response empty. If you require to drop connection with reset - RST
you can force it. Just set SO_LINGER
for the connection's socket. You may consider the api as public since there is no _
, but... it's kind a internal stuff (implementation dependent) of Tornado.
import socket
import struct
import tornado.ioloop
import tornado.web
from tornado.gen import coroutine
class MainHandler(tornado.web.RequestHandler):
@coroutine
def get(self):
s = self.request.connection.stream.socket
l_onoff = 1
l_linger = 0
s.setsockopt(
socket.SOL_SOCKET, socket.SO_LINGER,
struct.pack('ii', l_onoff, l_linger)
)
self.request.connection.close()
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", MainHandler),
])
application.listen(8888)
tornado.ioloop.IOLoop.current().start()
Upvotes: 1
Reputation: 24009
Decorate your method with asynchronous
and never call finish
:
class EchoHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
if not self.get_cookie("topsession"):
pass
else:
self.finish("0")
As the docs for asynchronous say:
If this decorator is given, the response is not finished when the method returns. It is up to the request handler to call self.finish() to finish the HTTP request.
So, if you simply return without calling finish
, the client waits forever (or until its client-side socket timeout) for a response without receiving one. If you do this, however, you must call finish
in the other branch of the if statement.
On the other hand if by "no response" you mean an error, you could do instead:
class EchoHandler(tornado.web.RequestHandler):
def get(self):
if not self.get_cookie("topsession"):
raise tornado.web.HTTPError(401) # Unauthorized.
else:
self.write("0")
Upvotes: 4