BairDev
BairDev

Reputation: 3201

Apache Rewrite, then Proxy, which order?

I know it should be pretty easy to use mod-rewrite and mod-proxy for a Vhost. But I cannot get the right order.

Here is what I want to achieve:

  1. Files (JS, CSS, images, fonts, etc.) should be delivered normally
  2. XHR requests for certain path (ibo-php) should be handled by a proxy, using another Vhost and http (not https)
  3. add a .php ending to all these data requests, matching the API path ibo-php
  4. The Vhost is there for a web-app, which has different app states as path, e.g. /my-app/view/sub-part/1, so these path parts need to be ignored

The rewrite rules do work for files, but the proxy does not. I am getting a 404 for my calls to the API: "POST /ec2-app/ibo-php/quarter HTTP/1.1" 404 645 "https://ec2.localhost/ec2-app/"

(Apache access log, ec2.localhost is the name of the Vhost)

I guess that there is something wrong with the order of rules:

# for avoiding 403 from https://stackoverflow.com/a/38353249/2092322
<Directory "/home/myname/work/sdp/frontends">
    Require all granted
    RewriteEngine On
    ProxyPreserveHost On

    # background https://stackoverflow.com/a/58307829/2092322
    # now: https://gkedge.gitbooks.io/react-router-in-the-real/content/apache.html
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ - [L]

    # the END flag might be a problem, but I currently think that ibo-php is not matched by this rule
    RewriteRule ec2-app/(.*)/(js|style|resources)/(.+)\.(.+)$ ec2-app/$2/$3.$4 [END]

    # "POST /ec2-app/ibo-php/quarter HTTP/1.1" 404 645 "https://ec2.localhost/ec2-app/"
    RewriteRule ec2-app/ibo-php/(.+)$ ec2-app/ibo-php/$1.php [L,PT]

    # anything else to index.html
    RewriteRule ec2-app/(.+) ec2-app/index.html [L]

    ProxyRequests Off
    <Proxy *>
        Require all granted
    </Proxy>
    ProxyPass ec2-app/ibo-php/ http://ibo-php.localhost:7010/
    ProxyPassReverse ec2-app/ibo-php/ http://ibo-php.localhost:7010/
</Directory>

Other sources: SO, mod_rewrite:

[Here] we proxy the request only if we can't find the resource locally. This can be very useful when you're migrating from one server to another, and you're not sure if all the content has been migrated yet.

RewriteCond "%{REQUEST_FILENAME}"       !-f
RewriteCond "%{REQUEST_FILENAME}"       !-d
RewriteRule "^/(.*)" "http://old.example.com/$1" [P]
ProxyPassReverse "/" "http://old.example.com/"

Discussion:

In each case, we add a ProxyPassReverse directive to ensure that any redirects issued by the backend are correctly passed on to the client.

Consider using either ProxyPass or ProxyPassMatch whenever possible in preference to mod_rewrite.

Question

Would all be more easy by using Alias or RewriteBase?

Upvotes: 1

Views: 1187

Answers (1)

BairDev
BairDev

Reputation: 3201

Solution

The right order is

<Directory "/home/myname/work/sdp/frontends">
    Require all granted
    RewriteEngine On

    # RewriteRule ec2-app/ibo-php/(.+)$ /ec2-app/ibo-php/$1.php [L,PT]

    # background https://stackoverflow.com/a/58307829/2092322
    # now: https://gkedge.gitbooks.io/react-router-in-the-real/content/apache.html
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ - [L]
    RewriteRule ec2-app/(.*)/(js|style|resources)/(.+)\.(.+)$ /ec2-app/$2/$3.$4 [END]

    # anything else to index.html
    RewriteRule ec2-app/(.+) /ec2-app/index.html [L]
</Directory>

LogLevel debug

ProxyPreserveHost On
# "POST /ec2-app/ibo-php/quarter HTTP/1.1" 404 645 "https://ec2.localhost/ec2-app/"
ProxyPassMatch ^/ec2-app/ibo-php/(.+)$ http://ibo-php.localhost:7010/$1.php
ProxyPassReverse ^/ec2-app/ibo-php/ http://ibo-php.localhost:7010/

ProxyPassMatch is not allowed in <Directory>.

Upvotes: 0

Related Questions