我试图简单地读取传递给python cgi脚本的json数据,但是当我调用sys.stdin时它会挂起。我用--hourour-stdin开始使用uWSGI并没有任何区别。我使用的是nginx - >带有cgi插件的uWSGI。
data = json.load(sys.stdin)
print "Status: 200 OK"
print "Content-Type: application/json"
print "Length:", len(data)
print ""
print data
编辑:如果我限制它读取的字符数,它就不会挂起。所以它等待EOF。我缺少一些uWSGI设置吗?
答案 0 :(得分:1)
您可以使用os.environ['CONTENT_LENGTH']
环境变量来读取确切的字节数,作为stdin未被CGI lib终止的解决方法。
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编码。
答案 1 :(得分:0)
让我先从一些背景开始。
这是一个description of the CGI protocol。页面上的两个亮点:
FastCGI允许单个长时间运行的进程处理多个用户请求,同时保持接近CGI编程模型,保留简单性,同时消除为每个请求创建新进程的开销。
您的问题是:每次请求后stdin都没有终止(EOF)。保持链接打开实际上是一个好主意。此外,前面的HTTP连接也可能是 keepalive 。
我从this page学到了一种通过fastCGI per-request环境变量检查请求结束的方法。它们可以通过os.environ
获得# read until EOF set in environment
while not os.environ.get("stdin_eof", True):
buf += sys.stdin.read(1)
另一个想法可能是使用增量JSON解析器,如ijson
。