Python CGI将正确的文本返回到curl,但浏览器显示尾随零
我用Python 3编写了这个简单的CGI应用程序:Python CGI将正确的文本返回到curl,但浏览器显示尾随零,python,apache,curl,cgi,Python,Apache,Curl,Cgi,我用Python 3编写了这个简单的CGI应用程序: #! /usr/bin/env python3.4 print("Content-type: text/html\n") print("AAAA") 如果我使用任何浏览器访问URL,我会看到一个页面显示:“AAAA 0”。它在Firefox、Chrome和Mac上的Safari以及iPhone上的Safari中都能准确地显示这一点。将“AAAA”更改为任何其他值都会相应地更改所有浏览器中的输出,但尾随的“0”始终保留在每个浏览器中 浏
#! /usr/bin/env python3.4
print("Content-type: text/html\n")
print("AAAA")
- 如果我使用任何浏览器访问URL,我会看到一个页面显示:“AAAA 0”。它在Firefox、Chrome和Mac上的Safari以及iPhone上的Safari中都能准确地显示这一点。将“AAAA”更改为任何其他值都会相应地更改所有浏览器中的输出,但尾随的“0”始终保留在每个浏览器中
- 浏览器的“视图源”始终显示预期的字符串+换行符(当然,浏览器将其视为空格),后跟意外的0:
AAAA 0
- 直接从服务器的命令行(./foo.py | hex)执行它,并使用十六进制编辑器查看输出,生成预期的输出:标题行和内容行,内容行为41 0A(“AAAA\n”)
- 从我的Mac笔记本电脑和Linux服务器的命令行使用curl同样会产生我期望的十六进制输出:41 0A
- 任何(测试)平台上的旋度均不显示尾随零。所有平台上的所有浏览器都会显示尾随的零
- 如果我删除了第二条“print”语句,只为标题保留了一条“print”语句,则所有浏览器中的尾随“0”都会消失,只留下一个空白页,但是如果我在标题打印之后放置任何print语句,则所有浏览器中都会出现尾随的零,但不会出现在任何浏览器中。即使是一个空的“print()”也会在“view source”的第二行生成一个空的第一行(我相信是换行符),后跟一个“0”。如果我添加更多的打印行,插入正确的doctype&html,则在源代码中的end-html标记后会显示尾随的零。如果打印除标题以外的任何内容,浏览器源中将显示一个尾随的零
- 更改为Python3.2没有任何区别
- 因此,为了使curl-spoof成为一个浏览器,我从几个浏览器中添加了“用户代理”。没有区别。Curl仍然始终显示我期望它显示的内容,并且所有浏览器仍然显示一个尾随的零
- 重新键入简单代码(不是复制和粘贴)以确保没有不可见的字符会产生相同的结果(Python源代码的十六进制视图、在服务器上运行的输出以及curl获得的输出都不会显示额外的字符)
- 这是使用Apache+CGI共享主机,我没有更改任何Apache文件或创建任何.htaccess文件
- 我可以使用mod_wsgi,它可以很好地工作,如果这是为了生产,但它是为了学习。我试图教孩子们如何使用低级CGI,让他们手动从ENV变量中提取GET数据,等等,这样他们可以在升级到更多的预构建功能(CGI模块,然后是WSGI,然后是Flask,等等)之前看到下面发生了什么。重点是要理解发生了什么,但我没有
尾随的“0”可能来自分块响应格式,但浏览器不应显示它 如果您为响应添加了一个大小正确的“Content-Length”头,那么就应该取消它的权限,因为Apache不会使用分块响应,因为只有在长度未知的情况下才会使用分块响应 如果您使用“telnet”连接到服务器并手动发出请求,您将获得什么样的完整输出
telnet server-hostname 80
然后输入:
GET /some/url HTTP/1.0
Host: virtual-hostname
之后有一个额外的空行。只是为了踢,在脚本末尾抛出一个
sys.exit(1)
。查看是否打印了1。嘿,这是一个很好的猜测,但是,不,在sys.exit(1)作为最后一行时,它在浏览器中仍然显示尾随零,在curl中没有尾随任何内容。请尝试运行curl--忽略内容长度
。当您这样做时,0
是否显示?您的apache是否在chroot监狱中运行?如果是这样的话,您能在chroot内部手动运行CGI脚本吗?尝试编写一个简单的sh CGI:#/bin/sh
/echo“内容类型:text/html”
/echo”“
/echo“AAAA”
。CGI的行为如何?当我这样做时,它会在nginx的503页上显示一个错误,说明该网站尚未建立。共享主机来自Web派系,如果我没记错的话,他们前面有一个nginx服务器,它将直接为静态.html页面提供服务,或者将动态页面转发给Apache实例,例如CGI调用或(您出色的)mod_wsgi。上面的telnet命令显然没有通过nginx,即使我请求静态主页。正如你所猜测的,问题消失了。必须这样做很烦人,因为我们不能简单地边打印边打印,而是必须生成输出,连接它,测量它,然后输出标题,但是我们要用mod_wsgi实现这一点,所以哦,好吧。我仍然想知道到底发生了什么,为什么它会出现在所有浏览器中,而不是在curl中。你能在你的问题中添加你从telnet测试中获得的完整输出,而不包含内容长度吗。然后我也许可以明白为什么。Graham,正如我上面所说的,您的telnet测试永远不会到达Apache。相反,nginx返回相同的超长pla
GET /some/url HTTP/1.0
Host: virtual-hostname