Issue
Our PHP-based application (custom made, no framework) sometimes needs to use its base full URL (for instance to store URL in files send to clients). Based for instance on this question, our application guess this (this is based on comparing __FILE__
and various variables in $SERVER
like SCRIPT_NAME
and SERVER_NAME
).
Now we need to setup a (nginx) reverse-proxy in front of our application. Suppose that we map https://example.com/some/dir/onproxy/
to http://backend/another/dir/onbackend/
.
Is there a way to guess the public URL (https://example.com/some/dir/onproxy/
) from the code on backend
?
AFAIU (from my readings and experiments), it's not possible (HTTP_HOST
may give example.com
but I have found nothing that indicates some/dir/onproxy
) but maybe I'm missing something (some variables or a nginx configuration option).
Any idea ?
In case it's not possible, the only solution is to store https://example.com/some/dir/onproxy/
in the configuration, right ?
EDIT 1
As suggested by @Progman, I tried solutions on this question. I have tried both the accepted answer and the second most upvoted answer but both return (some variation of) the URL on the backend (http://backend/another/dir/onbackend/
).
EDIT 2
I forgot to mention that I would like to avoid to rely on URL rewriting in the proxy.
Solution
Since Nginx is changing the request before it reaches the PHP backend, the solution is to add the original request data in somehow to the proxied request.
A common used convention for this is to add the original data in as extra HTTP headers. See X_Forwarded_For as an example of this.
To add the original request path as a new header, add a proxy_set_header directive to Nginx.
location /some/dir/onproxy/ {
rewrite ^/some/dir/onproxy/(.*)$ /another/dir/onbackend/$1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Request-URI $request; #** This adds the original path as a header **
proxy_set_header Host $http_host; # **Optional, will retain the original host name**
proxy_pass http://backend;
}
Something similar to that in your configuration will proxy the original request to a PHP web server on the back end. It does assume the backend is a HTTP server and not PHP-FPM.
Within PHP the quickest way to get the value of a single HTTP header is via $_SERVER. The original request path will be in $_SERVER['HTTP_X_REQUEST_URI']
.
This is just an example, you may need to test and debug your application to refine the solution. php_info(); is a useful debug tool for the PHP environment, however it would also be useful to malicious actors so remove from your code as soon as possible or take other measures to ensure it is not exposed.
Answered By - Steve E. Answer Checked By - Marilyn (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.