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!
Related
I've never been good at .htaccess, I'm trying to copy and paste some code that worked on another one of my domains and modify it to work here. I will have several rewritten URLs, some static, some dynamic, but I can't even get the simplest of them to work. This one is testable here: http://lindseymotors.com/home
Clearly, index.php is available because if you access http://lindseymotors.com it works.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.* [NC]
RewriteRule ^home$ index.php
RewriteRule ^home/$ index.php
# When answering, if you could write a statement that would combine
# both of the statements above into one that would be appreciated.
As I said, these same conditions worked on another one my domains because I copied the code right over. I asked my server admin to double check everything on his end and it was fine. Any ideas?
Only thing I can think of is make sure the use of .htaccess is really on. The easiest way you can check since your server admin says it's fine is to put random text at the top of your .htaccess file. If your .htaccess file is being read and .htaccess files are enabled, it should throw a 500 internal server error. If not, then they don't have .htaccess files enabled and need to add AllowOverride All to the Apache config vhost.
Here is your rule combined into one as you noted. You really don't need the RewriteCond, but I will leave since you were using it previously.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.* [NC]
RewriteRule ^home/?$ index.php [L]
Possible this question has already been answered but I didn't find any answer after hours of searching.
I need to put the site under "maintenance mode" and redirect/rewrite all requests to site_down.html, but at the same time I need the site to be available if I enter the address like files are in a subfolder.
ex:
if I type http://example.com/login.php I need site_down.html to be displayed.
but if I specify http://example.com/test/login.php I need real login.php do be displayed.
I need this to be done with rewrite, so copying everything to another directory isn't a solution.
I tried a couple dozens of combinations, but I'm still unable to achieve what I need
This is one version of my .htaccess file ():
DirectoryIndex site_down.html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^test\/(.*)$ $1 [S=1]
RewriteRule ^(.*\.php)$ site_down.html
RewriteRule .* - [L]
</IfModule>
This code should rewrite all requests with "test/*" to "parent folder" and skip next rewrite rule and then terminate rewriting at RewriteRule .* - [L]. If there is no "test/" in url - all request should be rewritten to site_down.html
What am I doing wrong?
Could you suggest any valid solutions, please?
Thank you.
Essentially, you are searching for 2 rules. One rule will translate a virtual subdirectory to the working files. The other rule will translate the url to the working files to a splash page. We just have to make sure that if the first rule matches, the second rule doesn't match. We can do this by making sure " /test/" (including that leading space) was not in THE_REQUEST (or the string that the client sent to the server to request a page; something in the form of GET /test/mypage.php?apes=bananas HTTP/1.1). THE_REQUEST doesn't change on a rewrite, which makes it perfect for that. Skipping a rule like you did usually doesn't have the effect you expect, because mod_rewrite makes multiple passes through .htaccess until the resulting url doesn't change anymore, or it hits a limit and throws an error. The first time it will skip the rule, but the second time it will not do that.
RewriteCond %{THE_REQUEST} !\ /test/
RewriteRule \.php site_down.html [L]
RewriteRule ^test/(.*)$ $1 [L]
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.
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'd like to structure my website like this:
domain.com/person/edit/1
domain.com/person/edit/2
domain.com/person/edit/3
etc.
I have a page to which all these requests should go:
domain.com/person/edit.html
The JavaScript will look at the trailing part of the url when the page is loaded so I want the server to internally ignore it.
I've got this rewrite rule:
RewriteRule ^person/view/(.*)$ person/view.html [L]
I'm sure that I'm missing something obvious but when I visit one of the pages above I get this 404 message:
The requested URL /person/view.html/1 was not found on this server.
As far as I understood it the [L] means that if this rule applies Apache should stop rewriting and serve up the alternate page. Instead it seems to be applying the rule at the earliest possible moment and then appending the rest of the unmatched url to the re-written one.
How do I get these re-writes to work properly?
"As far as I understood it the [L] means that if this rule applies Apache should stop rewriting and serve up the alternate page."
Well .. [L] flag tells Apache to stop checking other rules .. and rewrite goes to next iteration .. where it again checks against all rules again (that is how it works).
Try these "recipe" (put it somewhere on top of your .htaccess):
Options +FollowSymLinks -MultiViews
# activate rewrite engine
RewriteEngine On
# Do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
Another idea to try -- add DPI flag to your [L]: [L,DPI]
If Options will not help, then rewrite rule should. But it all depends on your Apache's configuration. If the above does not work -- please post your whole .htaccess (update your question).