Apache ModRewrite strip part from request_uri in rewriteCondition

mod-rewrite

so basically I have a link in my html domain.com/app/css/build/app-23471942834.css however on the server the file actually lives in /fs/current/public/css/build/app-23471942834.css. Is there a way to check if a file exists in a RewriteCondition? The problem is that I basically need the /css/build/app-23471942834.css part to check, without the /app. Is there a way to remove this in a condition?

So I need:

  • domain.com/app/login to be rewritten to /fs/current/public/login
  • domain.com/app/build/css/app-123523.css to be rewritten to /fs/current/public/build/css/app-123523.css
  • domain.com/app/build/js/app-123523.js to be rewritten to /fs/current/public/build/js/build/app-123523.css

I am using Laravel so within my public directory there is another .htaccess by default with this:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

Sorry, but I really suck at htaccess files. Thanks for your help.

What I got so far:

RewriteCond %{HTTP_HOST} ^(www.)?domain.de$ [NC]
RewriteCond %{DOCUMENT_ROOT}/fs/current/public/$1 -f
RewriteRule ^app/(.*)$ /fs/current/public/$1 [L]

RewriteCond %{HTTP_HOST} ^(www.)?domain.de$ [NC]
RewriteRule ^app/(.*)$ /fs/current/public/index.php?/$1 [L]

SOLUTION:

I solved my issue like this:

RewriteCond %{HTTP_HOST} ^(www.)?domain.de$ [NC]
RewriteCond %{REQUEST_URI} \.(css|jpg|gif|png|js|svg)
RewriteRule ^app/(.+)$ /fs/current/public/$1 [L]

So all the rewrite only applies to css/jpg/gif/png/js/svg I think the issue I had before, was that the index.php file was rewritten by the script as well.

Best Answer

Try the following:

RewriteEngine On
RewriteRule ^/?app/(css/build/app)-\d+(\.css)$ /fs/current/public/$1$2 [L]

Not sure exactly what you are after, but this will internally rewrite a URL of the form domain.com/app/css/build/app-23471942834.css to /fs/current/public/css/build/app.css.

If you need to check that the destination file exists before rewriting then you can add a condition before the RewriteRule (although I'm not sure why you would need to do this, as you'll get a 404 regardless). For example:

RewriteCond %{DOCUMENT_ROOT}/fs/current/public/$1$2 -f

UPDATE#1: From comments...

I would need to rewrite anything that is not a file

Ah ok, that makes more sense. You can replace the above RewriteCond directive with the following:

RewriteCond %{REQUEST_FILENAME} !-f

That will only process the following RewriteRule substitution if the requested URL did not match a file on the filesystem.

UPDATE#2: From updated question...

A more general solution, after the existing RewriteEngine directive, try the following in .htaccess:

RewriteCond %{DOCUMENT_ROOT}/fs/current/public/$1 -f
RewriteRule ^app/(.+)$ /fs/current/public/$1 [L]

This will only rewrite the request if a file of the form <document-root>/fs/current/public/css/build/app-23471942834.css or <document-root>/fs/current/public/login exists on the filesystem.

Related Topic