簡體   English   中英

Python CGI 腳本在 uWSGI 嘗試讀取 sys.stdin 時掛起

[英]Python CGI script hangs with uWSGI trying to read sys.stdin

我試圖簡單地讀取傳遞給 python cgi 腳本的 json 數據,但是當我調用 sys.stdin 時它掛起。 我用 --honour-stdin 啟動了 uWSGI,它沒有任何區別。 我正在使用 nginx -> uWSGI 和 cgi 插件。

data = json.load(sys.stdin)
print "Status: 200 OK"
print "Content-Type: application/json"
print "Length:", len(data)
print ""
print data

編輯:如果我限制它讀取的字符數,它將不會掛起。 所以它在等待EOF。 是否有一些我遺漏的 uWSGI 設置?

讓我從一些背景開始。

這里是CGI 協議描述 頁面中的兩個亮點:

  1. 傳統的 CGI 會為每個請求分別調用 perl/python/... 解釋器。
  2. FastCGI 使解釋器保持活動狀態:

FastCGI 允許單個、長時間運行的進程處理多個用戶請求,同時保持接近 CGI 編程模型,在保留簡單性的同時消除為每個請求創建新進程的開銷。

您的問題是:每次請求后標准輸入都不會終止(EOF)。 保持鏈接打開實際上是性能的一個好主意。 此外,前面的 HTTP 連接也可能是keepalive

我從這個頁面學到了一種通過 fastCGI per-request 環境變量檢查請求結束的方法。 它們可以通過 os.environ 獲得

# read until EOF set in environment
while not os.environ.get("stdin_eof", False):
    buf += sys.stdin.read(1)

另一個想法可能是使用像ijson這樣的增量 JSON 解析器。

您可以使用os.environ['CONTENT_LENGTH']環境變量來讀取確切的字節數,作為標准輸入不被 CGI 庫終止的解決方法。

import os

if not os.environ['CONTENT_LENGTH']:
    data = {}
else:
    post_length = int(os.environ['CONTENT_LENGTH'])
    # post_length stores byte count, but stdin.read, apparently, takes the character count
    post_string = sys.stdin.buffer.read(post_length).decode('utf-8')
    data = json.loads(post_string)

假設您的文本以 utf-8 編碼。

暫無
暫無

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

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