Why is PATH_INFO URI decoded?
To be compatible with CGI spec (RFC 3875) and most web servers’ implementations (like Apache and lighttpd). I understand it could be inconvenient that you can’t distinguish foo%2fbar from foo/bar in the trailing path, but the CGI spec clearly says PATH_INFO should be decoded by servers, and that web servers can deny such requests containing %2f (since such requests would lose information in PATH_INFO). Leaving those reserved characters undecoded (partial decoding) would make things worse, since then you can’t tell foo%2fbar from foo%252fbar and could be a security hole with double encoding or decoding. For web application frameworks that need more control over the actual raw URI (such as Catalyst), we made the REQUEST_URI environment hash key REQUIRED. The servers should set the undecoded (unparsed) original URI (containing the query string) to this key. Note that REQUEST_URI is completely raw even if the encoded entities are URI-safe. For comparison, WSGI (PEP-333) defines both SCRIPT