为什么我的WSGI应用总是在environ['PATH_INFO']中获取解码后的路径?

6 投票
1 回答
1978 浏览
提问于 2025-04-17 21:30

我有一个简单的 WSGI 应用程序:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    print('PATH_INFO:', environ['PATH_INFO'])
    return [b'<p>Hello World</p>']

if __name__ == '__main__':
    from wsgiref import simple_server
    server = simple_server.make_server('0.0.0.0', 8080, application)
    server.serve_forever()

我发出了两个请求:

C:\>curl "http://localhost:8080/<foo>"
<p>Hello World</p>
C:\>curl "http://localhost:8080/%3Cfoo%3E"
<p>Hello World</p>

我得到了这个输出:

C:\code>python foo.py
PATH_INFO: /<foo>
127.0.0.1 - - [09/Mar/2014 13:48:39] "GET /<foo> HTTP/1.1" 200 18
PATH_INFO: /<foo>
127.0.0.1 - - [09/Mar/2014 13:48:47] "GET /%3Cfoo%3E HTTP/1.1" 200 18

你看,我的应用程序得到了 URL 解码后的路径 /<foo>,即使客户端请求的是 /%3Cfoo%3E

这说明 wsgiref.simple_server 确保我的应用程序总是能在 environ['PATH_INFO'] 中获取到解码后的路径。

不过,我在 PEP-3333 的文档中找不到这个行为的相关说明。你能帮我找到一个官方文档,说明这个行为吗?

1 个回答

2

REQUEST_URI的值来自实际的HTTP请求行,如果服务器提供这个值的话,可能是这样的:

REQUEST_URI: '/%3Cfoo%3E'

即使你使用了:

curl "http://localhost:8080/<foo>"

也是这样,因为curl在发送之前会对URL进行编码,用%符号来表示一些特殊字符。

我认为REQUEST_URI并没有被任何RFC(互联网标准文档)覆盖,但很多服务器会提供这个变量。不过,你不能完全依赖它的存在,所以在写你的WSGI应用时,不要假设它一定会有。

在处理REQUEST_URI之前,网络服务器会解码其中的%符号。最终出现在PATH_INFO中的结果总是会是:

PATH_INFO: '/<foo>'

这个解码过程是由CGI和相关的RFC文档规定的,而WSGI就是基于这些文档构建的。

例如,你可以查看:

撰写回答