簡體   English   中英

如何在 BaseHTTPServer.BaseHTTPRequestHandler Python 中實現超時

[英]How to implement Timeout in BaseHTTPServer.BaseHTTPRequestHandler Python

在我的 python 腳本中,我試圖運行一個 Web 服務器:

server = BaseHTTPServer.HTTPServer(('127.0.0.1',8080), RequestHandler)

我有一個請求處理程序類:

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        # Doing Some Stuff.

現在我總是在 do_GET 中等待一些數據。 我想實現一個超時操作,我希望這個 Web 服務器在 60 秒后關閉。 我無法實現這一點。 請建議我在這種情況下如何實現 Web 服務器的自動關閉操作。

謝謝塔拉辛格

假設我已經正確理解了您的問題,您無法在do_GET實現讀取超時,因為在調用此方法時已經讀取了請求。

由於BaseHTTPRequestHandler擴展了StreamRequestHandler ,而后者又擴展了BaseRequestHandler ,您可以覆蓋setup()以使用超時初始化套接字:

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def setup(self):
    BaseHTTPServer.BaseHTTPRequestHandler.setup(self)
    self.request.settimeout(60)

  def do_GET(self):
    # ...

我實際上發現如果我然后調用超類,在 def setup 中為 self.timeout 設置一個值不起作用。 看起來在創建 HTTPServer 實例期間沒有調用 Handler 的 setup 和init方法。 我使用 pydevd 來確認這一點。

所以,我倒退了一步:

httpd = BaseHTTPServer.HTTPServer(server_address, MyHttpHandler)
httpd.timeout = 10

它完美運行,無需覆蓋核心代碼,也無需構建您自己的派生類。 如果您想這樣做,看起來您必須覆蓋 HTTPServer 代碼,而不是 Handler 代碼。

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    timeout = 60 # StreamRequestHandler.setup
    def do_GET(self):
        # Doing Some Stuff.

我設法讓超時為 HTTP 請求工作

self.rfile._sock.settimeout(60)

希望這可以幫助

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def __init__(self, request, client_address, server):
    BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server)   
    self.timeout = 60
timeout = 0.1  # seconds

class WebHTTPServer(BaseHTTPServer.HTTPServer):
    def server_bind(self):
        BaseHTTPServer.HTTPServer.server_bind(self)
        self.socket.settimeout(timeout)

class WebReqHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    <etc> 

if __name__ == '__main__':
    server = WebHTTPServer(('',port), WebReqHandler)
    while 1:
        server.handle_request()
        <do other things>

正如Tey'TinBane的回答中所指出的, timeout屬性不適用於serve_forever()方法,如文檔中所述:

server_forever

解決方法是使用自定義循環來處理user3483992指出的請求

while True: server.handle_request()

handle_request()然后將在給定的超時結束時按預期觸發方法handle_timeout()

在此處輸入圖片說明

...除了 handle_timeout 方法什么都不做:

在此處輸入圖片說明

一個解決方案是為此方法提供另一種實現,例如(信用在這里):

server.handle_timeout = lambda: (_ for _ in ()).throw(TimeoutError())

簡而言之:

try:
     server = HTTPServer(('', PORT_NUMBER), `yourAwesomeRequestHandler`)
     server.timeout = 10
     server.handle_timeout = lambda: (_ for _ in ()).throw(TimeoutError())
     while True: server.handle_request()
except TimeoutError:
    // TODO

鑒於 python 的 http.server 模塊的流行, python3 -m http.server的一個最小的插入式復制粘貼替換可能對找到此頁面的其他人有用:

~20 秒超時:

python3 -c "from http.server import HTTPServer, SimpleHTTPRequestHandler
import time
start = time.time()
httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler)
while not time.time() - start > 20:
    httpd.handle_request()"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM