.htaccess mod_rewrite.c using HTTP_REFERER - apache

I am trying to get .htaccess to fetch the page http://www.example.org/aa/exists.php when http://www.example.org/aa/doesntexist.php is entered in the URL bar. The .htaccess file is clearly functional, because the DirectoryIndex line is producing the desired result, with http://www.example.php in the URL bar fetching the page http://www.example.php/aa/default.php.
I tried adapting the response to how to redirect using HTTP_REFERER on htaccess to my situation, but without success.
Below is the full text of my .htaccess file.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} ^(.*)www\.example\.org/aa/doesntexist\.php [NC]
RewriteRule ^(.*)(www\.example\.org/aa/)doesntexist\.php(.*)$ $1$2exists.php$3 [NC,L]
DirectoryIndex aa/default.php
</IfModule>
A request for http://www.example.org/aa/doesntexist.php yields the following error:
Not Found
The requested URL /aa/doesntexist.php was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

Try adding Options +FollowSymlinks and Allow Override All as first commands before turning the engine on.
I couldn't see anything wrong in your condition or rule. I recently had a very similar problem that could be solved that way.
If that's not the problem, you might have a look at http://forum.modrewrite.de/topic82.html
It's in German, unfortunately, but maybe stil helpful - at least by aid of google translate (surely not perfect, but good enough).
Btw.: if there is a reason for checking the referrer and not only the requested URI, keep it. Else, the rule alone will do what you want. There is no need for a condition if the content of the condition matches the pattern of the rule.

Related

Apache httpd.conf rewrite rules

I have some rewrite rules in my httpd.conf file. Is there a way to get apache to check the rewrite rules only if the url is not valid? My rewrite rules are preceded by checks for the REQUEST_FILENAME being a valid file, and a valid folder. But the documentation mentions that the rewrite conditions are checked only AFTER it finds a match for the rewrite rule.
So, whenever there is a request for a URL, apache checks each rewrite rule for that URL. Almost all the pages have images, .js and .css files and a few more files with them. Apache checks those too, against the rewrite rules in the httpd.conf (I see this in the RewriteLog generated for each URL). This significantly slows down the site.
I am aware of the FallbackResource directive. I don't want to use it as of now, because it returns a http status code of 200 by default. I want to return the correct status code (usually a 301) whenever there is a request for a page that was not found by Apache (usually, the incorrect URL has a correct counterpart, hence the need to send a 301). Sending the correct http status code also benefits our seo efforts. If there is a way to send the correct http status code using the FallbackResource directive, I would be open to using that option.
I have tried googling for these issues, and didn't find an answer. I have tried with different RewriteCond (s) but, like the documentation says, each rewriterule is checked anyways.
Any pointers on this would be of much help.
It does appear that there'd be some readings to do for you but, I always use this as "bible" when it comes to rewrite rule and haven't ceased to failed me. Perhaps this would do the same for you.
http://corz.org/server/tricks/htaccess2.php
Why not use the following:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /not-found.php [L]
I would put in a .htaccess file located in the root folder. That way you can easily customize it for each site.

My rewrite rule isn't working

I currently want my site to rewrite from
.com/page/1234
to
.com/?view=page&id=1234
Heres my .htaccess content:
RewriteBase /
RewriteRule ^/page/([0-9]+)$ /index.php?view=page&id=$1
ErrorDocument 404 errors/404.html
When I type ".com/page/1" my site just redirects to the 404 page.
What have I done wrong? I tried to the simplest:
RewriteRule ^/page$ /about.php
But it doesn't work either. So I'm having some suspect that 000webhost (my current host) is not supporting RewriteRule although they stated they support it.
From personal experience, I know they -do- support RewriteRule, but it is somewhat horrible to test them. In "per-directory"-context, the slash from a directory is appended to the "prefix" part of the url. .htaccess always works as in "per-directory"-context. A RewriteRule that begins with a slash in .htaccess will therefore never match anything.
If you change your .htaccess to the following, everything should work as expected:
RewriteBase /
RewriteRule ^page/([0-9]+)$ /index.php?view=page&id=$1
ErrorDocument 404 errors/404.html
I recommend reading the documentation for mod_rewrite. It contains a lot of useful information.

Can I write an HTML response from an .htaccess file

Apologies if this is a stupid question, but can I control the HTML response from a .htaccess file (Apache)?
In other words something like (psuedo code) Write <!DOCTYPE html><html>...[etc]
The reason I ask is because I would like to "take down" some sites in one "hit", but without replacing any files or having any other kind of holding page.
I found the answer myself, certainly worked for what I needed:
ErrorDocument 503 "<!DOCTYPE html><html><head><title>This website is undergoing maintenance</title></head><body style='font-family: sans-serif'><h1>This website is undergoing maintenance</h1></body></html>"
RewriteEngine On
RewriteRule .* - [R=503,L]
Hope this helps somebody
No its not possible to produce HTML content into a rewritten URI. However what you can do is to have a HTML file pre-written let's call it outage.html which will be placed in your DOCUMENT_ROOT.
Then enable mod_rewrite and .htaccess through httpd.conf and place this code on top of your .htaccess:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
#RewriteRule (?!^outage\.html$)^.*$ /outage.html [L,NC]
Whenever you want to bring the site down just uncomment above RewriteRule line by removing # and your site will just show outage.html to visitors for every URL.

change file-name with .htaccess

My main question is, for security reasons, I'd like to know if it's possible to virtually change the name (in a sense) of a website file using .htaccess. For instance, if I have a file /index.php and I want to make it such that calls for /mysite are redirected to /index.php, but I also want calls to /index.php to return as either an error 403 or 404. Is this possible? And if so, how could it be done?Also, I've been searching for a full documentation on the .htaccess directive syntax, but I couldn't find anything. My second question is, Does anyone know of a good generic reference of all the directives and their syntax? (I couldn't even find one in w3schools)
First I'll start by saying w3schools doesn't have particularly good references for anything. The Apache mod_rewrite documentation is really good, and I always go there first.
The first part of your request is pretty straightforward as a rewrite. But before we get there, let's start by preventing direct requests to index.php. In order to do this without messing up our other rules we will use the %{THE_REQUEST} variable to match index.php and forbid access.
RewriteEngine On
# If the request sent by the browser includes index.php...
RewriteCond %{THE_REQUEST} index\.php
# forbid access (403)
RewriteRule ^. - [F]
# Then you just need a generic rule to rewrite /mysite into index.php
RewriteRule ^mysite index.php [L]
We need the first part using THE_REQUEST to avoid causing conflicts with the second part rewriting into index.php.
If you want to serve a 404 to make it look like index.php doesn't even exist, replace the [F] with [R=404,L]

Mod-Rewrite Problems (Apache) with / slashes

I am betting on an obvious problem here I am not seeing.
Here's the important bits for those of you familiar with Mod-Rewrite
.htaccess file with mod-rewrite rules exists here:
http://www.thedomain.com/.htaccess
User goes to this URL:
http://www.thedomain.com/test/blog
Mod-Rewrite rules should actually tell the server to access this URL:
http://www.thedomain.com/index.php?page=blog
.htaccess:
Options FollowSymLinks
Options -MultiViews
RewriteEngine on
RewriteRule ^test/([^/.]+)$ /index.php?page=$1 [L]
This combination of code/request does not work. If you're wondering about the code snippet ^test not being ^/test instead, it is because apparently this is a problem on GoDaddy, the code fails with the / after the ^ - this seems like it may be related to my problem, which I'll explain further... If I change the .htaccess code line:
RewriteRule ^test/([^/.]+)$ /index.php?page=$1 [L]
to
RewriteRule ^test([^/.]+)$ /index.php?page=$1 [L]
(just removing the / here: ^test/([^/.]+) )
The code works when the requested URL is changed to accomodate (remove the slash; http://www.thedomain.com/testblog) as the user views the proper index.php?page=blog server response. It seems to me I cannot use any slashes within the darn match side of the RewriteRule. What gives?
Update: If at all relevent, this .htaccess file and the relevant files to the question all exist in a subdirectory off of the GoDaddy server that is hosting this although the domain points to the subdirectory as the root. Not sure if this is relevant.
Update: This server (at the server root) is actually running wordpress with pretty URLs enabled and they work perfectly fine. I assume wordpress uses mod-rewrite to make crazy urls like thedomain.com/2008/11/15/the-article-title.html work...?
Thanks so much.
Is RewriteBase what you're looking for?
there is a nice test utility for windows here
http://www.helicontech.com/download-isapi_rewrite.htm
try changing your code to:
^/test/([^/]+)$ /index.php?page=$1 [L]
or without slashes
^test[^a-z]+([a-z]*)$ /index.php?page=$1 [L]
I was unable to find a solid method around this problem on GoDaddy; for whatever reason I could not have slashes within the URL that was attempting to be rewritten aside from the base (http://www.somedomain.com/testingthis would work but http://www.somedomain.com/testing/this died).
I ended up instead using the Wordpress .htaccess to send all non-existant file/directory requests back to my index.php. I then used the $_SERVER['REQUEST_URI'] var with pathinfo() to parse the URL and then direct what content to load from the parsing. This works well, is fast, and is probably the same method Wordpress uses.
Thanks for the attemps!
If you're wondering about the code snippet ^test not being ^/test instead, it is because apparently this is a problem on GoDaddy, the code fails with the / after the ^ […]
That’s not odd but necessary:
Per-directory Rewrites
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done.
And that per-directory prefix is for a .htaccess file in the document root (/.htaccess) the URL path root (/). Thus patterns with the ^ must be written without that per-directory prefix /.
On the same way the substitution is handled. After a rule is applied, the per-directory prefix is added to the substituion. So try this rule:
RewriteRule ^test/([^/.]+)$ index.php?page=$1 [L]
OK, first off, I think that the GoDaddy apache server simply has some of the options turned off. I think that if they don't have an AllowOverride FileInfo in their configuration, RewriteRule won't work so well, or at all.
Which means its surprising that the URL http://www.thedomain.com/testblog works at all, and gets re-written. So I guess I'm a little confused.
Here's an idea: Try creating a directory named test, and put the .htaccess file in there! It would look like this:
Options FollowSymLinks
RewriteEngine on
RewriteRule ^([^/]+)$ /index.php?page=$1 [L]
OK, another idea: Use RewriteCond. Maybe you can check the request URI directly, like this:
Options FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/test/([^/]+)
RewriteRule . /index.php?page=%1 [L]
Last idea: maybe your browser sees the URL http://www.thedomain.com/test/blog and thinks it's a directory, and adds a slash? So the URL is sends is http://www.thedomain.com/test/blog/. In that case, the REGEX won't match unless you allow for a trailing slash:
RewriteRule ^test/([^/.]+)/?$ /index.php?page=$1 [L]
Whoops. Sorry for gushing - there's just some many things that can go wrong in an HTTP request that goes through rewriting, and as many ways to try and overcome the problems :-)