Tomcat 8 URL Rewrite Issues - apache

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.

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.

I seem to have got it fixed. There are couple of things i found and sharing it for others. The below thing worked finally for me. Below are the contents in rewrite.config. It should be placed in webapps//WEB-INF/ directory.
RewriteCond %{REQUEST_URI} .*\.(css|js|html|png|jpg|jpeg|gif|txt|ttf|json|woff|ico)$ [OR]
RewriteCond %{REQUEST_URI} ^(/api/).*$ [OR]
RewriteRule ^(.*)$ - [L]
RewriteRule ^(.*)$ /index.html
There are a couple of things that were needed. The way i ensure my app is the default app is by adding below snippet in HOST configuration in server.xml. Please note that if you are using this approach to make your app the default app the valve adding should be done in the Context block in server.xml and it works and putting the same in your application/META-INF/context.xml does not seem to do the trick. It surely loads the configuration but rewrite does not happen. The PreResources thing kept in the application/META-INF/context.xml seems to work fine.
server.xml snippet
<Host name="localhost" appBase="webapps"
unpackWARs="false" autoDeploy="false" deployOnStartup="false">
<Context path="" docBase="myapp" reloadable="false">
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" asyncSupported="true"/>
</Context>
....
</Host>
HTH, Thanks

Related

Apache 2.4 .htaccess friendly URL rewrite

Having some issues understanding the .htaccess file and getting it to work properly. .htaccess is recognized....i entered plain test at the top and got the internal server error. And it appears mod-rewrite is working...because I downloaded a test php file and it works.
I am using Apache 2.4.23 with no php pages
However i cant seem to get this to work right.
I am trying to take this url
http://example.com/ProjectTest/index.shtml?dynContent=Content1
and rewrite it like this
http://example.com/ProjectTest/Content1
I am also trying to do this generically across the site since ?dynContent=whatever will be a constant.....and trying to keep the same path.....like the below example
Change this
http://example.com/ProjectTest/ProjectFolder/index.shtml?dynContent=Content1
to this
http://example.com/ProjectTest/ProjectFolder/Content1
I am not very good with the .htaccess files
UPDATE: Ok...I got this to work.....not really sure why it works....but when I type in the test-dev/ProjectTest/apples or test-dev/ProjectTest/oranges it calls up the appropriate content.
This is what I used
RewriteRule ^ProjectTest/([^/\.]+)/?$ ProjectTest/index.shtml?dynContent=$1 [L]
and then I rewrote it to be this and now it works for any directory
RewriteRule ^(.*)/([^/\.]+)/?$ $1/index.shtml?dynContent=$2 [L]
Try this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^dynContent=(.+)$
RewriteRule ^/(.+)+/index.shtml $1/%1 [PT]
This requires mod_rewrite to be activated. The value of the bracket in dynContent=(.+) is stored in %1 and the bracket's value in ^/(.+)+/index.shtml is stored in $1. Both together creates your target path http://example.com/ProjectTest/ProjectFolder/Content1

Allowing relative paths only

I believe this is an Apache .htaccess issue, and yet, maybe not. Maybe I am looking at the problem from the wrong angle, and thus can't find the proper solution.
I am building a web app + hybrid mobile app. I would like to share the exact same code base, without having to tweak anything manually to deploy my app to Android or iOS, otherwise, the process of deploying will be hacky and painful. What I want is to take the web app repository, shove it into Cordova's box (you dirty man ;), and it would deploy it successfully.
Now, one issue is that Cordova requires relative paths to work properly. For example, this is how I include my require.js file :
<script data-main="library/js/dependencies.js" src="library/js/libs/require.js">
</script>
This works fine on the hybrid app. This works fine also on most of the web app's URLs, those with the following scheme :
domain.com/view_name
However, this is what happens when I load the app from a view that receives URI parameters :
domain.com/view_name/6iwO4NyJqy
The relative paths are not resolved properly anymore. I get 404 error due to unproper paths. For instance, this is how is resolved the require.js file above :
http://domain.com/view_name/library/js/libs/require.js
The view_name bit is the wrong part. It should not be there. Without it, the file would be found successfully.
This is my .htaccess file :
RewriteEngine on
RewriteBase /
# REROUTING EVERYTHING TO index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule .* /index.html [NC,L,QSA]
Is there a way to set my .htaccess file, so that I don't need to modify the relative paths within the app, and still can have them resolved properly ?
Any suggestion is most welcome.
It is not caused by your rewrite rule, it is due to your use of relative paths.
You can add this just below <head> section of your page's HTML:
<base href="/" />
so that every relative URL is resolved from that base URL and not from the current page's URL.

PERL Dancer2, cgi dispatcher and uri_for helper

I have a web interface that i need to maintain and improve, written in a plain old CGI.pm way. That app is not using templating system neither. It's served by apache, like that:
/var/www/vhost/myapp/cgi-bin/app.cgi
/htdocs/css/styles.css
/htdocs/js/script.js
To add new pages to that app, and make my life easyer, i want to host a Dancer or Dancer2 app next to it, i was thinking about something like that:
/var/www/vhost/myapp/cgi-bin/app.cgi
/cgi-bin/dispatch.cgi (the one from Dancer2)
/htdocs/css/styles.css
/js/script.js
/dancer_public/...
/dancer2/lib/...
/views/...
/environement/...
In the dispatcher, i'm changing the path to reach the Dancer2 bin/app.psgi.
I added the following .htaccess file to the htdocs dir:
# BEGIN dancer application htaccess
RewriteEngine On
RewriteBase /v2
RewriteRule ^/v2$ /cgi-bin/dispatch.cgi [L]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule v2/(.*) /cgi-bin/dispatch.cgi/$1 [L]
# END dancer application htaccess
By doing that,
accesssing to example.com/cgi-bin/app.cgi show me the old app
as expected
accesssing to example.com/v2 show me the dancer
app home page, default one, without css, which is expected as i moved
the public dir, and some other modification
Now that you have the setup, here is where i have an issue,
the redirection from v2 to the dancer app is working really well, however, in order to keep consistent, i would like to have the uri_for creating url from v2 , but it's using the SCRIPT_NAME as base url, to show the issue, when i'm creating that url: uri_for('/mypage'),
i would like to have that url : example.com/v2/mypage,
but instead i have url example.com/cgi-bin/dispatch.cgi/mypage
SCRIPT_NAME environment variable is containing cgi-bin/dispatch.cgi , i have one terrible hack, that is working, but clearly not the solution, i can have my expected behavior by forcing SCRIPT_NAME to /v2 in the cgi dispatcher, in a BEGIN block.
If someone as a clean solution for that, that would be of a great help!
Thanks
Have the same problem with D1.
$ENV{SCRIPT_NAME} = '';
inside dispatch.fcgi helps me.

Inspecting apache setting - loading weird css output when the file size is over 255B

This is a little bit tricky trouble.
I was setting up a new development environment, which includes the below:
vagrant 1.6.3
Apache/2.2.15 (Unix)
php 5.4.32
ZendFrameword2
The trouble I am running into is that I can't refresh the change of css file properly.
What I have tried is,
put META tags for no-cache like
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
force a browser to get the latest file by
<link rel="stylesheet" type="text/css" charset="utf-8" href="/path/to/css_file.css?<?php time() ?>" />
But I found out there is no difference with the above.
I found that I make it to refresh a css file with the following process
remove the css file
access from my browser and confirm it doesn't exit by showing error message.
and remake the css file and access it.
I get a refreshed file.
Next, I google about Cashing Algorithm for ZendFramework2, and test loading with ZF2 files that may relate to caching control.
It resulted no ZF2 File is related when just to load css file.
Then I notice that if the css file is quite small, it properly refreshed. so I checked various condigions and I found out that I get this trouble when the file size is over 255B.
the rest of part I can inspect is, .htaccess or apache setting files on a server.
.htaccess file under the public directory of ZF2 is:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L]
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ RewriteRule ^(.*) - [E=BASE:%1] RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
RewriteCond %{REQUEST_URI} ^/phpmyadmin/(.*)$ RewriteRule ^.*$ - [L]
Do you guess any causes? any advice?
I haven't solved this question yet, but I specified what is the problem actually.
The matter is,
What apache module is lacking when I can't write over 255byte in a file on document root?
so, I am closing this question for now.
Finally! I got the true problem and have solved it.
Additional Experiments after the first post are
1) I replicated the same situation with .js file, and .index
→ So I confirmed that it was not a trouble about css
2) I replaced simple htdocs directory with the one with ZF2 to simplify the situation and discovered that the phenomenon still happened.
→ ZF2 has nothing to do with this problem.
3) I suspected Apache settings next, so I stoped apache and installed and started nginx. Surprisingly for me, the trouble kept happening.
→ Apache settings / modules are not causing the problem.
4) directory errors on guest OS working on vagrant hit to my mind, and vagrant up again with a different synced folder
→ I got no difference.
5) I was finally sure that vagrant is somehow causing this problem, and found the true cause after a few minutes of search.
The solution for this problem is
to add
EnableSendfile off
for httpd.conf if you use apache, and
sendfile off;
for nginx
Related links are below:
Vagrant/VirtualBox/Apache2 Strange Cache Behaviour
https://coderwall.com/p/ztskha
http://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/

Apache RewriteCond - Works local, not on Host

I have a .htaccess rewrite condition / rule, which works fine on my local, which is OSX mavericks, running apache Apache/2.2.26, but when I deploy to my production server it no longer works, running Apache/2.2.22 (Debian).
this is the condition:
RewriteCond %{REQUEST_URI} ^([a-z]{2})/sitemap.xml$
RewriteRule ^([a-z]{2})/sitemap.xml /sitemaps/$1_sitemap.xml [NC,L]
As you can see, I have a directory for sitemaps in the base directory, and this being a multi-lingual site, I have a sitemap for each language. However I cannot simply create a directory like /en/sitemap.xml for each one, as this effects how the framework deals with the request, as apache trys to serve the directory, rather than passing it to the index file to be handled.
So i create this rewrite condition, which should rewrite the request /en/sitemap.xml to /sitemaps/en_sitemap.xml and as stated, this works great locally, but not on my Debian server, it never matches that regex from the request, it just moves onto the next one and passes the request to the index.php file.. which is wrong!
Any advice / help would be great, I cannot find anything in apache docs referring to mod_rewrite under these 2 versions that may be different.
Thanks
That's because %{REQUEST_URI} value always begins with a leading slash.
Also, your condition is useless since your RewriteRule does the same.
This code should work as expected on both sides
RewriteRule ^([a-z]{2})/sitemap\.xml$ /sitemaps/$1_sitemap.xml [L]