How to make php_fastcgi respect a rewritten uri in REQUEST_URI?

1. The problem I’m having:

I need requests to potential PDF-Files with a “.pdf” extension be normalized to their non-extension file name when handed to the index.php router via the php_fastcgi directive (the CMS behind does not work with file extensions but another requesting client needs it).

I tried a rewrite, a map and finally uri strip_suffix .pdf. But i noticed the REQUEST_URI variable is set to the original request.

I assume there is a solution to this, e.g. via using reverse_proxy directives in php_fastcgi or via overwriting some ENV in the latter directive, but i had no luck so far. I’m thankful for any suggestions.

2. Error messages and/or full log output:

DEBUG	http.handlers.rewrite	rewrote request ... "uri": "/test.pdf", ... "method": "GET", "uri": "/test"}
DEBUG	http.reverse_proxy.transport.fastcgi	roundtrip ... "uri": "/index.php" ...  "env": {"REQUEST_URI": "/test.pdf", ...

3. Caddy version:

v2.6.4

4. How I installed and ran Caddy:

b. Command:

caddy start
wget https://localhost/test.pdf

d. My complete Caddy config:

{
	log {
		level debug
		format console
	}
}
localhost {
	root * ./www
	uri strip_suffix .pdf
	php_fastcgi 127.0.0.1:55335
	file_server
}

The CGI spec dictates that REQUEST_URI must be the original unmodified URL from the client.

Really, it’s the app’s responsibility to handle this, because the app has its own routing layer.

That said, it is possible to override, but it’s quite hacky and I don’t recommend it if you can avoid it.

@pdf path_regexp pdf (.*).pdf$
vars @pdf cleaned_path {re.pdf.1}
vars cleaned_path {uri}

php_fastcgi 127.0.0.1:55335 {
	env REQUEST_URI {vars.cleaned_path}
}

Hi Francis, thanks a lot. I tested this snippet and it works. In my requirements I can mitigate the hackiness by restricting the requests to only a dozen explicit paths that I know upfront.

May I ask why the second vars cleaned_path {uri} does not overwrite the vars @pdf cleaned_path {re.pdf.1} everytime?

The Caddyfile adapter will sort vars cleaned_path {uri} before vars @pdf cleaned_path {re.pdf.1}, so it will set it to {uri} first (important so there’s a default value set), then if @pdf matches then it will overwrite it with the regexp capture.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.