2017-07-24 9 views
2

Um meinen Client zu testen, möchte ich, dass einige der von meinem Client gesendeten HTTP-Anfragen keine Antwort erhalten.Wie man Anfrage in Tornado fallen lässt?

Zum Beispiel möchte ich jede Anfrage sollte Cookie topsession haben, wenn nicht, keine Antwort.

class EchoHandler(tornado.web.RequestHandler): 
    def get(self): 
     if not self.get_cookie("topsession"): 
      ###TODO 
     else: 
      self.write("0") 

Antwort

4

Dekorieren Sie Ihre Methode mit asynchronous und finish nie nennen:

class EchoHandler(tornado.web.RequestHandler): 
    @tornado.web.asynchronous 
    def get(self): 
     if not self.get_cookie("topsession"): 
      pass 
     else: 
      self.finish("0") 

Da die docs for asynchronous say:

Wenn dieser Dekorateur gegeben wird, wird die Reaktion nicht beendet, wenn die Methode zurückgibt. Es ist Aufgabe des Request-Handlers, self.finish() aufzurufen, um die HTTP-Anfrage zu beenden.

Wenn Sie also einfach ohne Aufruf finish zurückkehren, wartet der Client für immer (oder bis zu seinem clientseitige Socket-Timeout) auf eine Antwort ohne einen Empfang. Wenn Sie dies tun, müssen Sie jedoch finish im anderen Zweig der if-Anweisung aufrufen.

Auf der anderen Seite, wenn sie von „keine Antwort“ einen Fehler bedeuten, Sie stattdessen tun könnte:

class EchoHandler(tornado.web.RequestHandler): 
    def get(self): 
     if not self.get_cookie("topsession"): 
      raise tornado.web.HTTPError(401) # Unauthorized. 
     else: 
      self.write("0") 
2

Der zugrunde liegende Verbindung Wunsch kann

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() 

und den Test explizit geschlossen werden, mit 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 

Der obige Code schließt Zusammenhang mit FIN -flow und lässt die Antwort leer. Wenn Sie die Verbindung mit Reset - RST trennen müssen, können Sie es erzwingen. Setzen Sie einfach SO_LINGER für den Socket der Verbindung. Sie können die API als öffentlich betrachten, da es keine _ gibt, aber ... es ist eine Art internes Zeug (implementierungsabhängig) von 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() 
Verwandte Themen