I have a problem trying redirect some user requests to my Apache server pointing to non existing files, using something like this:
RewriteCond %{REQUEST_URI} !-f
RewriteRule ^/a/b/c.* /d/e$1 [L]
My intention is that, if some user requests file http://whatever.com/a/b/c/something, which doesn't exist, instead of sending the 404 error, rewrite the URL to get it from http://whatever.com/d/e/something, where I can be sure the file do exist.
I know there are a lot of topics on this, but I did very intense research, and my problem is no matter what combination I try, I can't seem to get the rewrite module to work..
Even with something like this :
RewriteRule ^(.*) /index.html [L]
That would presumably redirect EVERY petition to index.html , but it does nothing.
It is supposed to be loaded, as apache2ctl -M outputs rewrite_module as correctly loaded
Logging errors at debug level, I only see, users requesting non-existent files, and Apache answering '404 File does not exist' errors..
I'm the server admin so I'm not using .hcaccess, I edit directly the httpd.conf file, so there should be no overriding directives issues.
What am I missing?
RewriteCond %{HTTP_HOST} ^yourdomain.com
RewriteRule (.*) http://www.yourdomain.com/$1 [R=301,L]
...to redirect user to the index page.
Related
I have an e-commerce site that resides in:
http://dev.gworks.mobi/
When a customer clicks on the signin link, the browser gets redirected to another domain, in order for authentication:
http://frock.gworks.mobi:8080/openam/XUI/#login/&goto=http%3A%2F%2Fdev.gworks.mobi%3A80%2Fcustomer%2Faccount%2Flogin%2Freferer%2FaHR0cDovL2Rldi5nd29ya3MubW9iaS8%2C%2F
I'm trying to rewrite http://dev.gworks.mobi/* to http://frock.gworks.mobi:8080/openam/*, without redirection.
I've tried this in the .htaccess of the dev.gworks.mobi site:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/openam(.*)$ [NC]
RewriteRule ^(.*)$ http://frock.gworks.mobi:8080/$1 [P,L]
</IfModule>
But when I access http://dev.gworks.mobi/openam, it shows a 404 page not found page.
Can anyone help me to achieve my use case?
Try this:
RewriteEngine on
RewriteBase /
# Make sure it's not an actual file being accessed
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Match the host
RewriteCond %{HTTP_HOST} ^dev\.gworks\.mobi
# Rewrite the request if it starts with "openam"
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [L,QSA]
This will rewrite all the requests to dev.gworks.mobi/openam to frock.gworks.mobi:8080.
If you want to mask the URI in a way that it's not visible to the visitor that she's visiting the authentication app, you need to add a P flag. Please note that it needs Apache's mod_proxy module in place:
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [P,L,QSA]
Feel free to drop the L flag, if it's not the last rewrite rule. See RewriteRule Flags for more information.
The 404
If it's all in place and you're still getting a 404 error, make sure that the target URL is not throwing 404 errors in the first place.
Second, check if you're still getting the error with the correct referrer URI set. It might be designed in a way to throw a 404, if the referrer is not correctly set. If that's the case, which I suspect, you need to use the R flag and redirect instead of proxying the request.
Last thing that comes to my mind, some webapps are not built in a way to figure out the URI address. The host, as well as the port number, might be hard-coded somewhere in the config files. Make sure that the authentication app is able to be run from another URL without the need to edit the configs.
Test
You can test the rewriterule online:
I've not done much with mod_rewrite, but I can't seem to get anywhere with this. I'm wondering if perhaps it is not enabled on my server(even though my host says it is).
I have the following url: http://dev.website.com/folder1/translate/horse and I want that to redirect to: http://dev.website.com/folder1/translate.php?word=horse
My .htaccess starts with RewriteEngine on and I've tried various attempts to get it working, but no matter what, it just shows my home page (the default 404 redirect).
Things I've tried:
RewriteRule ^translate/.*$ translate.php?word=$1
RewriteRule ^translate translate.php
and some other things I don't remember, but I can't get anything to work.
The .htaccess file I am using is located in folder1. I have also tried putting random characters in the file to make it throw an error, and it does.
Anything I'm missing? How would I properly create this redirect?
As per request, this is my file structure.
I have the domain www.website.com, and a subdomain dev.website.com. The subdomain is set so that it redirects to www.website.com/dev. So, in this case, dev.website.com/folder1/translate.php = www.website.com/dev/folder1/translate.php. I am not sure how that masking is done, as it is accomplished via my web host's cpanel.
You aren't capturing $1 in brackets so this should work:
In DOCUMENT_ROOT/.htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^folder1/translate/(.*)$ /folder1/translate.php?word=$1 [L,QSA]
In DOCUMENT_ROOT/folder1/.htaccess:
RewriteEngine On
RewriteBase /folder1/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^translate/(.*)$ translate.php?word=$1 [L,QSA]
I am attempting to redirect any URLs that attempt to access a directory that doesn't exist, however I am getting a 404 when trying the following:
RewriteRule ^picco/(.*)$ /rangers/$1 [L,R=301]
There is no directory called picco however, when anyone tries to access a page picco/index.php for example I want to redirect to rangers/index.php.
Is this possible?
I've got it - the following works, it seems the introduction of RewriteBase had a substantial effect.
RewriteBase /
RewriteRule ^picco(.*)$ /rangers/$1 [R=301,L]
Here's my situation. I have a web root and several subdirectories, let's say:
/var/www
/var/www/site1
/var/www/site2
Due to certain limitations, I need the ability to keep one single domain and have separate folders like this. This will work fine for me, but many JS and CSS references in both sites point to things like:
"/js/file.js"
"/css/file.css"
Because these files are referenced absolutely, they are looking for the 'js' and 'css' directories in /var/www, which of course does not exist. Is there a way to use RewriteRules to redirect requests for absolutely referenced files to point to the correct subdirectory? I have tried doing things like:
RewriteEngine on
RewriteRule ^/$ /site1
or
RewriteEngine on
RewriteRule ^/js/(.*)$ /site1/js/$1
RewriteRule ^/css/(.*)$ /site1/css/$1
But neither of these work, even redirecting to only one directory, not to mention handling both site1 and site2. Is what I'm trying possible?
EDIT: SOLUTION
I ended up adapting Jon's advice to fit my situation. I have the ability to programatically make changes to my .htaccess file whenever a new subdirectory is added or removed. For each "site" that I want, I have the following section in my .htaccess:
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteCond %{HTTP_COOKIE} sitename=site1
RewriteCond %{REQUEST_URI} !^/site1/
RewriteRule ^(.*)$ /site1/$1 [L]
Index.php is a file that lists all my sites, deletes the "sitename" cookie, and sets a cookie of "sitename=site#" when a particular one is selected. My RewriteConds check,
If the request is not for /
If the request is not for /index.php
If the request contains the cookie "sitename=site1"
If the request does not start with "/site1/"
If all of these conditions are met, then the request is rewritten to prepend "/site1/" before the request. I tried having a single set of Conds/Rules that would match (\w+) instead of "site1" in the third Condition, and then refer to %1 in the fourth Condition and in the Rule, but this did not work. I gave up and settled for this.
If the RewriteRules are in your .htaccess file, you need to remove the leading slashes in your match (apache strips them before sending it to mod_rewrite). Does this work?
RewriteEngine on
RewriteRule ^js/(.*)$ /site1/js/$1
RewriteRule ^css/(.*)$ /site1/css/$1
EDIT: To address the comment:
Yes, that works, but when I do RewriteRule ^(.*)$ /site1/$1, it causes Apache to issue internal server errors. But to me, it seems like that should just be a generic equivalent of the individual rules!
What's happening with that rule is when /something/ gets rewritten to /site/something/, and apache internally redirects, it gets rewritten again, to /site/site/something/, then again, then again, etc.
You'd need to add a condition to that, something like:
RewriteCond %{REQUEST_URI} !^/site/
RewirteRule ^(.*)$ /site/$1 [L]
You need to set up symlinks, which the rewrite rules will use so your absolute links at the server level can follow the symbolic links to the central site hosting account.
I have the following code:
RewriteEngine on
RewriteRule ^user/([a-z]+)$ index.php?Agent=$1 [QSA]
theoretically any visitor to my site using the format:
www.site.com/user/username
should be directed to:
www.site.com/index.php?Agent=username
they are instead being treated as if /user is a real directory and as if /user/username is a valid file and exists (which it does not). Any ideas?
EDIT #1
I have modified my htaccess slightly and even stripped off the /user requirement, the following .htaccess file causes and 500 error, even when visiting the primary domain alone (www.site.com):
ErrorDocument 404 /404.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteRule ^(.+)$ index.php?Agent=$1 [QSA]
they are instead being treated as if /user is a real directory and as if /user/username is a valid file and exists (which it does not).
What exactly do you mean like this? What does it show?
Do you want to rewrite or **redirect?
Rewrite = call www.site.com/index.php?Agent=username when the user enters www.site.com/user/username
Redirect = redirect the user to the other URL so their address field says www.site.com/index.php?Agent=username
Right now, your code should rewrite, not redirect, which is probably what you want. Just checking...
Your problem might be that the username you're testing with contains capital letters. Add NC to make the match case insensitive.
RewriteRule ^user/([a-z]+)$ index.php?Agent=$1 [QSA,NC]
If you want to allow other characters than just the letters a-z, you can either add more characters to character class, or just write (.+) to match any character.
Edit
As per the question below, I think the infinite redirect happens because the rule is triggered again (and again) because the rewrites matches the new index.php request. Simply checking that the target of the redirect isn't a file should solve that. (-f = "is file". ! = negate condition.)
RewriteCond %{REQUEST_FILENAME} !-f
It should work. I am using pretty much that exact line for my rewrite. Here's what I've got:
RewriteRule ^history/(.+)?$ history.php?display_name=$1 [QSA,L]
Note the "L" flag, which means mod_rewrite should stop at this point, and not process any other rewrite rules. Do you have any other rewrite rules after this one?
Are you putting this in .htaccess? Make sure it's being processed at all. Put some random junk in there and load a page. Apache should show you an error page, complaining about a server misconfiguration. If it doesn't, it's not even looking at your .htaccess file. Make sure in your apache configuration, "AllowOverride" is set to "FileInfo Options" for the directory in which this webpage lives.
This is a stab in the dark but I suggest that you recheck your Apache configuration file apache2.conf file to make sure that mod_rewrite is enabled.
Look for a line like this :
#LoadModule rewrite_module modules/mod_rewrite.so
and change it to:
LoadModule rewrite_module modules/mod_rewrite.so
EDIT: Then restart your web server for the changes to take effect!
Hope this helps!