Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Recently we had to move /task to /public/task, and I'd like to configure Apache to redirect accordingly.

However, using mod_rewrite, though it works in the browser, seems to break applications making api calls to the above location. What happens is the application returns a page with the message saying the page was moved, but the app doesn't follow the redirect.

So, is there a way to simply forward any traffic to /task to /public/task without 'redirecting', i.e, returning a redirect status code?


EDIT: Here's a little more information. I've found a simple test to clarify what I'm trying to fix. Here is the URL path that needs forwarding:

https://mydomain.com/task

Needs to go to:

https://mydomain.com/public/task

If I use curl against the original domain, it just returns a redirect page notice. If I add the -L flag, which tells curl to follow redirects, it then follows the redirect successfully.

I assume something very similar is happening in the application (which I don't have access to) that makes calls to the /task URL path. Since I cannot modify the application to make it follow redirects properly, I'm looking for a solution I can implement in Apache.


EDIT 2: Thanks everyone for you input. ryanm's suggestion of using the [P] flag in the rewrite worked. Here's everything that I did:

Apache has three ways apparently to forward or redirect vistors to a URL: Alias, Proxy and Rewrite.

Alias seems like the most obvious solution since it silently forwards the vistor to the new specified location. Unfortunately this didn't work for me becauce Aliases require specifying the new location on the actual filesystem, and with Jboss, that location changes at each redeploy/restart.

Using ProxyPass also seemed like it would work, and it possibly could, but every way I configured it, curl would return an empty result, and it didn't look like anything was happening. Here is the Proxy command I used to no avail:

ProxyPass /task http://localhost:8080/public/task

Finally, redirecting (with the [P] flag) fixed the problem. My initial redirect looked like this:

RewriteRule ^/task/(.*)$ public/task/$1 [R,L]

With the [R], Apache was returning redirect headers to the client, which worked fine in any browser, but caused applications like curl to stop a page that told them to redirect. Curl needed the -L flag to then follow the redirect.

Finally, using a combination of ProxyPass and Rewrite, I was able to get it to work. I used that [P] flag at ryanm's suggestion and curl would now follow the redirect without having to use the -L flag. My final directive looked like this:

RewriteRule ^/task/(.*)$ http://localhost:8080/public/task/$1 [P]

Thanks again everyone for the help!

share|improve this question
    
What do your "API calls" look like? .htaccess rules are only going to apply for http(s) connections, not for something accessing your files with a filesystem path-- /var/www/... –  s_ha_dum Nov 2 '12 at 15:10
    
Not sure. I don't have access to the API calls, but basically they are simply hitting "https: //mydomain/task", and the forward needs to send them to "https: //mydomain/public/task". –  DrewVS Nov 2 '12 at 15:16
    
That answered my question. :) mod_rewrite should be able to handle that. What does your .htaccess rule(s) for this look like? But if symlinks are a possibility it might be more efficient. Is it possible to symlink the two directories? –  s_ha_dum Nov 2 '12 at 15:23
    
Yea, unfortunately mod_rewrite doesn't automatically redirect for you. It returns a redirect status with the new location, and it's up to the client/application to actually follow that redirect. I've put a little more information in my question that hopefully clarifies the issue. –  DrewVS Nov 2 '12 at 15:30
    
Here's the apache rewrite rule: RewriteRule ^/task/(.*)$ public/task/$1 [R,L] –  DrewVS Nov 2 '12 at 15:42

3 Answers 3

up vote 3 down vote accepted

I've used mod_alias successfully without giving the client a redirect; this was from a browser-requested URL /request/ to an internal directory /opt/myapplication.

However, if that solution does not work for some reason, have you considered a mod_rewrite proxy flag or a proxy setup? It's the same server, but if alias doesn't work, proxy may work to the localhost.

share|improve this answer
    
Awesome! This worked. I was really tearing my hair out with this issue. I'll add an edit to my post to fully explain the solution. –  DrewVS Nov 2 '12 at 23:43

Not knowing what kind of applications are running on the server, you might be able to do it with an Alias. Something like:

Alias /task /var/www/.../public/task
share|improve this answer

I am assuming that you are on a *nix server of some kind.

I can think of two ways to approach this that might work.

1) symlink the two directories. ln -s /path/to/domain/public/task /path/to/domain/task This is not strictly an Apache answer but it may execute more quickly than an Apache solution. You will need Options FollowSymLinks for the domain's configuration.

2) Apache aliases This is the answer posted by chultz, so if you go with this pick his as the solution. He got there first. You will need mod_alias for this one.

share|improve this answer
1  
Alias does seem to be the correct solution as it does a forward rather than a redirect. However, this is a Jboss application in Java and the WAR file gets exploded newly each deployment of JBoss. Not sure how to get around that –  DrewVS Nov 2 '12 at 16:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.