Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat 8 URL Rewrite Issues

I have got the tomcat 8 rewrite to work but seems to missing something in rewrite.config that is causing the last condition to not execute. For benefit of others, i have the RewriteValve to work for my specific application and not globally. What works for me is given below.

In my app's META-INF context.xml file i have included below line

<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" asyncSupported="true"/>

In my app's WEB-INF, i have a rewrite.config file that says below things after incorporating the feedback seen in the other tomcat 8 rewrite thread, regarding issue with using {REQUEST_FILENAME} being null. I have not used the REQUEST_FILENAME and my config looks like below.

RewriteCond %{REQUEST_URI} .*\.(css|js|html|png|jpg|jpeg|gif|txt|ico) [OR]
RewriteCond %{REQUEST_URI} ^\/api\/ [OR] 
RewriteRule ^(.*)$ - 

RewriteRule ^(.*)$ /index.html 

Now if URI is a js,css etc or if the URI starts with /api/ i see the rewrite rule is being evaluated and no substitution is being done. i.e below urls seem to work ok and no substitution is being done. localhost:8080/api/abc/xyz , localhost:8080/css/abc.min.css

But for some reason the last rule is not getting hit at all even when the URI has a valid one to get hit by it.For ex. URL like localhost:8080/def/ghi should have got redirected to index.html, but it seem to not getting rewritten. I am not sure what am i missing in the rewrite.config causing this behavior. I could move to a ! condition to do the rewrite too, but just want to get my understanding clear when i use Mulitple RewriteRule combination.

Any help is appreciated.

like image 637
Arvind N Avatar asked Jan 05 '16 19:01

Arvind N


1 Answers

I found this question because I had a similar problem. I spent hours looking for a solution that didn't require me to whitelist specific file types. Eventually I decompiled org.apache.catalina.valves.rewrite.RewriteValve and found the answer.

My case is similar, but my Angular app is nested inside an older non-Angular app. That means that the URL to it someting like http://localhost:8080/mywebapp/ng/index.html (the app's base-href is thus "/mywebapp/ng").

I had no luck with rules using REQUEST_URI, REQUEST_FILENAME, or SCRIPT_FILENAME. What worked for me was SERVLET_PATH (no idea why).

I wound up with a solution including these two files:

/META-INF/context.xml:

<?xml version='1.0' encoding='utf-8'?>
<Context>
    <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>

/WEB-INF/rewrite.config:

RewriteCond %{SERVLET_PATH} !-f
RewriteRule ^/ng/(.*)$ /ng/index.html [L]

The result is that everything which is not a real file gets served by the Angular app.

Note: This worked on Tomcat 8.0 with an AoT compiled Angular2 (v4.0.0) app nested in an existing web-application.

like image 85
mhvelplund Avatar answered Sep 28 '22 12:09

mhvelplund