gpt4 book ai didi

python - 如何从 CGI 脚本发送响应头和状态

转载 作者:行者123 更新时间:2023-11-28 22:47:51 27 4
gpt4 key购买 nike

我正在使用 CGIHTTPServer.py用于创建简单的 CGI 服务器。如果某些操作出错,我希望我的 CGI 脚本处理响应代码。我该怎么做?

我的 CGI 脚本中的代码片段。

if authmxn.authenticate():
stats = Stats()
print "Content-Type: application/json"
print 'Status: 200 OK'
print

print json.dumps(stats.getStats())
else:
print 'Content-Type: application/json'
print 'Status: 403 Forbidden'
print
print json.dumps({'msg': 'request is not authenticated'})

来自请求处理程序的一些片段,

def run_cgi(self):
'''
rest of code
'''
if not os.path.exists(scriptfile):
self.send_error(404, "No such CGI script (%s)" % `scriptname`)
return
if not os.path.isfile(scriptfile):
self.send_error(403, "CGI script is not a plain file (%s)" %
`scriptname`)
return
ispy = self.is_python(scriptname)
if not ispy:
if not (self.have_fork or self.have_popen2):
self.send_error(403, "CGI script is not a Python script (%s)" %
`scriptname`)
return
if not self.is_executable(scriptfile):
self.send_error(403, "CGI script is not executable (%s)" %
`scriptname`)
return

if not self.have_fork:
# Since we're setting the env in the parent, provide empty
# values to override previously set values
for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
'HTTP_USER_AGENT', 'HTTP_COOKIE'):
env.setdefault(k, "")

self.send_response(200, "Script output follows") # overrides the headers

decoded_query = query.replace('+', ' ')

最佳答案

可以实现对覆盖 HTTP 状态行的 Status: code message header 的支持(HTTP 响应的第一行,例如 HTTP/1.0 200 OK) .这需要:

  1. CGIHTTPRequestHandler 进行子类化,以诱使其将 CGI 脚本的输出写入 StringIO 对象,而不是直接写入套接字。
  2. 然后,在 CGI 脚本完成后,使用 Status: header 中提供的值更新 HTTP 状态行。

这是一个 hack,但还不错,不需要修补标准库代码。

import BaseHTTPServer
import SimpleHTTPServer

from CGIHTTPServer import CGIHTTPRequestHandler
from cStringIO import StringIO

class BufferedCGIHTTPRequestHandler(CGIHTTPRequestHandler):
def setup(self):
"""
Arrange for CGI response to be buffered in a StringIO rather than
sent directly to the client.
"""
CGIHTTPRequestHandler.setup(self)
self.original_wfile = self.wfile
self.wfile = StringIO()
# prevent use of os.dup(self.wfile...) forces use of subprocess instead
self.have_fork = False

def run_cgi(self):
"""
Post-process CGI script response before sending to client.
Override HTTP status line with value of "Status:" header, if set.
"""
CGIHTTPRequestHandler.run_cgi(self)
self.wfile.seek(0)
headers = []
for line in self.wfile:
headers.append(line) # includes new line character
if line.strip() == '': # blank line signals end of headers
body = self.wfile.read()
break
elif line.startswith('Status:'):
# Use status header to override premature HTTP status line.
# Header format is: "Status: code message"
status = line.split(':')[1].strip()
headers[0] = '%s %s' % (self.protocol_version, status)

self.original_wfile.write(''.join(headers))
self.original_wfile.write(body)


def test(HandlerClass = BufferedCGIHTTPRequestHandler,
ServerClass = BaseHTTPServer.HTTPServer):
SimpleHTTPServer.test(HandlerClass, ServerClass)

if __name__ == '__main__':
test()

不用说,这可能不是最好的方法,您应该看看非 CGIHTTPServer 解决方案,例如一个微型框架,例如 bottle ,合适的网络服务器(根据内存,不建议将 CGIHTTPServer 用于生产用途)、fastcgi 或 WSGI - 仅举几个选项。

关于python - 如何从 CGI 脚本发送响应头和状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25800385/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com