httpd rewrite and REQUEST_URI value

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

httpd rewrite and REQUEST_URI value

Scott Vanderbilt-2
I was very eager to implement the new rewrite functionality in httpd.
However, I've run into an issue, and I am uncertain whether the new
behavior is CGI-compliant or not.

The app I am attempting to convert to httpd is currently built on nginx,
and the rewrite functionality it offers satisfies all of my app's needs.
But for a variety of reasons, I would prefer to use httpd. My goal is to
implement a RESTful API, which involves rewriting all requests for
"virtual" resources to target an index.php page, which uses the SlimPHP
micro framework to handle routing and all other tasks related to
servicing requests. That routing relies on the value of the REQUEST_URI
parameter to perform its work.

In httpd.conf, I have this rewrite rule:

         location match "/hello/.*" {
                 request rewrite "/index.php"
         }

while in nginx, I have this one:

         try_files                      $uri /index.php;

         location /index.php {
                 fastcgi_pass unix:run/php-fpm.sock;
                 fastcgi_param           SCRIPT_FILENAME
$document_root$fastcgi_script_name;
                 include                 fastcgi_params;
         }

For the URL: http://example.com/hello/fred, here are the differing
values of REQUEST_URI:

     nginx: /hello/fred

     httpd: /index.php

Based on the definition in the httpd.conf(5) man page,  which says
$REQUEST_URI contains "the request path and optional query string", I
would have expected that the original value of REQUEST_URI would have
been preserved even after the rewrite. Otherwise, there is no way for
the target resource to know the original (pre-rewrite) URI. Unless, of
course, it was embedded within the rewritten URI as a query string by
the rewrite directive in the .conf file. But that's not very practical
if the original URI already has a query string.

Am I correct in assuming the REQUEST_URI's value should not be altered
by the rewrite operation? If the post-rewrite URI is meant to be borne
by DOCUMENT_URI, why also change the value of REQUEST_URI? This makes no
sense to me.

Many thanks in advance for any enlightenment you can provide.



Reply | Threaded
Open this post in threaded view
|

Re: httpd rewrite and REQUEST_URI value

Ve Telko
Hi Scott.

If you or your framework uses REQUEST_URI you don't need
request rewrite feature. Using REQUEST_URI and request
rewrite feature are two oposite solutions for the same problem.
To mimic nginx's try_files do something like this:

location match "/hello/.*" {
    ....
    root "/index.php"
    ....
}

It is not obvious from man page but file can act as document
root :) Then in that file, index.php in this case, you can route
requests by parsing $_SERVER['REQUEST_URI'] what your
framework probably does.

Ve.

Reply | Threaded
Open this post in threaded view
|

Re: httpd rewrite and REQUEST_URI value

Scott Vanderbilt-2
On 6/24/2018 10:25 PM, Ve Telko wrote:

> If you or your framework uses REQUEST_URI you don't need
> request rewrite feature. Using REQUEST_URI and request
> rewrite feature are two oposite solutions for the same problem.
> To mimic nginx's try_files do something like this:
>
> location match "/hello/.*" {
>      ....
>      root "/index.php"
>      ....
> }
>
> It is not obvious from man page but file can act as document
> root :) Then in that file, index.php in this case, you can route
> requests by parsing $_SERVER['REQUEST_URI'] what your
> framework probably does.

Thank you for your reply. I finally got an opportunity to test your
suggested workaround, but it does not appear to work.

Request as logged in error log:

        server nomina2.onomasticon.org, client 1 (1 active),
162.229.162.103:53790 -> 162.229.162.102:443, /hello/fred (404 Not Found)


Request as logged in access log:

        nomina2.onomasticon.org 162.229.162.103 - scott [30/Jun/2018:10:20:47
-0700] "GET /hello/fred HTTP/1.1" 404 0

The index.php file is in the location specified:

$ ls -al /var/www/htdocs/lpn/src/public/
total 24
drwxr-xr-x  4 root  daemon   512 Jun 21 13:13 .
drwxr-xr-x  5 root  daemon   512 Jun 20 17:43 ..
-rw-r--r--  1 root  daemon  1081 Jun 23 07:00 index.php
....


 From httpd.conf:

server "nomina2.onomasticon.org" {
         listen  on $ext_addr tls port 443
         directory index index.php
         root    "/htdocs/lpn/src/public"

         log     access onom_access.log
         log     error onom_error.log

         authenticate finklejinkleheimer with "/conf/ok_users"

         tls certificate
"/etc/ssl/acme/nomina2.onomasticon.org/fullchain.pem"
         tls key
"/etc/ssl/acme/private/nomina2.onomasticon.org/privkey.pem"

         location "*.php" {
                 fastcgi socket "/run/php-fpm.sock"
         }

         location "/.well-known/acme-challenge/*" {
                 no authenticate
                 root "/htdocs/lpn/src/acme"
                 request strip 2
         }

         # Block user access to these files
         location "/composer\.(json|lock)" {
                 block   return 404
         }

         location match "/hello/.*" {
                 root    "/htdocs/lpn/src/public/index.php"
         }

         location match "/old/(.*)" {
                 request rewrite "/new/%1"
         }
}

server "nomina2.onomasticon.org" {
         listen on $ext_addr port 80
         block return 301 "https://$HTTP_HOST$REQUEST_URI"
}