How to debug .htaccess RewriteRule not working - apache

I have a RewriteRule in a .htaccess file that isn't doing anything. How do I troubleshoot this?
How can I verify if the .htaccess file is even being read and obeyed by Apache? Can I write an echo "it is working" message, if I do write it, where would that line be echoed out?
If the .htaccess file isn't being used, how can I make Apache use it?
If the .htaccess is being used but my RewriteRule still isn't having an effect, what more can I do to debug?

Enter some junk value into your .htaccess
e.g. foo bar, sakjnaskljdnas
any keyword not recognized by htaccess
and visit your URL. If it is working, you should get a
500 Internal Server Error
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request....
I suggest you to put it soon after RewriteEngine on.
Since you are on your machine. I presume you have access to apache .conf file.
open the .conf file, and look for a line similar to:
LoadModule rewrite_module modules/mod_rewrite.so
If it is commented(#), uncomment and restart apache.
To log rewrite
RewriteEngine On
RewriteLog "/path/to/rewrite.log"
RewriteLogLevel 9
Put the above 3 lines in your virtualhost. restart the httpd.
RewriteLogLevel 9 Using a high value for Level will slow down your Apache server dramatically! Use the rewriting logfile at a Level greater than 2 only for debugging!
Level 9 will log almost every rewritelog detail.
UPDATE
Things have changed in Apache 2.4:
FROM Upgrading to 2.4 from 2.2
The RewriteLog and RewriteLogLevel directives have been removed. This functionality is now provided by configuring the appropriate level of logging for the mod_rewrite module using the LogLevel directive. See also the mod_rewrite logging section.
For more on LogLevel, refer LogLevel Directive
you can accomplish
RewriteLog "/path/to/rewrite.log"
in this manner now
LogLevel debug rewrite_module:debug

The 'Enter some junk value' answer didn't do the trick for me, my site was continuing to load despite the entered junk.
Instead I added the following line to the top of the .htaccess file:
deny from all
This will quickly let you know if .htaccess is being picked up or not. If the .htaccess is being used, the files in that folder won't load at all.

Generally any change in the .htaccess should have visible effects. If no effect, check your configuration apache files, something like:
<Directory ..>
...
AllowOverride None
...
</Directory>
Should be changed to
AllowOverride All
And you'll be able to change directives in .htaccess files.

To answer the first question of the three asked, a simple way to see if the .htaccess file is working or not is to trigger a custom error at the top of the .htaccess file:
ErrorDocument 200 "Hello. This is your .htaccess file talking."
RewriteRule ^ - [L,R=200]
On to your second question, if the .htaccess file is not being read it is possible that the server's main Apache configuration has AllowOverride set to None. Apache's documentation has troubleshooting tips for that and other cases that may be preventing the .htaccess from taking effect.
Finally, to answer your third question, if you need to debug specific variables you are referencing in your rewrite rule or are using an expression that you want to evaluate independently of the rule you can do the following:
Output the variable you are referencing to make sure it has the value you are expecting:
ErrorDocument 200 "Request: %{THE_REQUEST} Referrer: %{HTTP_REFERER} Host: %{HTTP_HOST}"
RewriteRule ^ - [L,R=200]
Test the expression independently by putting it in an <If> Directive. This allows you to make sure your expression is written properly or matching when you expect it to:
<If "%{REQUEST_URI} =~ /word$/">
ErrorDocument 200 "Your expression is priceless!"
RewriteRule ^ - [L,R=200]
</If>
Happy .htaccess debugging!

Perhaps a more logical method would be to create a file (e.g. test.html), add some content and then try to set it as the index page:
DirectoryIndex test.html
For the most part, the .htaccess rule will override the Apache configuration where working at the directory/file level

If you have access to apache bin directory you can use,
httpd -M to check loaded modules first.
info_module (shared)
isapi_module (shared)
log_config_module (shared)
cache_disk_module (shared)
mime_module (shared)
negotiation_module (shared)
proxy_module (shared)
proxy_ajp_module (shared)
rewrite_module (shared)
setenvif_module (shared)
socache_shmcb_module (shared)
ssl_module (shared)
status_module (shared)
version_module (shared)
php5_module (shared)
After that simple directives like Options -Indexes or deny from all will solidify that .htaccess are working correctly.

To test your htaccess rewrite rules, simply fill in the url that you're applying the rules to, place the contents of your htaccess on the larger input area and press "Test" button.
http://htaccess.mwl.be/

Check whether the permission to read and execute the .htaccess by apache process is possible. Looking into the error_log of Apache will help you to sort the permission related error.

Why not put some junk in your .htaccess file and try to reload apache. If apache fails to start you know its working. Remove the junk then reload apache if it loads congrats you configured .htaccess correctly.

Related

Apache HTTPD - recursively deny specific file extensions and/or subdirs?

I have an Apache 2.4 web server, and in its htdocs folder, there is a complicated structure of directories and subdirectories.
Is it possible to create a single, top-level .htaccess file that would deny specific file extensions (e.g. .bak)
and/or traversing into specific directory names (e.g. .git)
for the whole subdirectory structure?
E.g., I would like to respond with HTTP 403 Forbidden when requested:
htdocs/index.html.bak
htdocs/aaa/bbb/ccc/login.php.bak
htdocs/foooooooo/.git/subdir/some_pic.png
If not via .htaccess, then perhaps this can be achieved via httpd.conf?
Thanks!
Thanks! I ended up with the following .htaccess:
RewriteEngine On
RewriteRule \.bak$ - [F]
RewriteRule (^|/)\.git($|/) - [F]
Of course, this line in httpd.conf has to be uncommented first:
LoadModule rewrite_module modules/mod_rewrite.so

MASKING URL with HTACCESS

I am trying to redirect visitors of alldomain.com to the domain newdomain.com it does redirect however I want that when the user open's alldomain.com the data should be of newdomain.com however the top url should be alldomain.com
My Current HTACCESS:
RedirectMatch .* http://www.newdomain.com
I believe the solution to this consist of two parts: correct .htaccess, and using mod_proxy on your Apache server:
Uncomment these lines in httpd.conf (and restart Apache!):
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Add the following lines to your .htaccess:
RewriteEngine on
RewriteRule .* http://www.newdomain.com/ [P]
ProxyPassReverse / http://www.newdomain.com/
The key here is that the [P] flag in the RewriteRule tells Apache to use mod_proxy (which you enabled earlier), and the ProxyPassReverse makes sure that any links from the new domain are properly "attributed" to the old domain as well. I think that does it, but I can't test... Let me know whether this works for you!

alias_module doesnot work

In my httpd.conf file of my apache server(on windows7), I used LoadModule alias_module modules/mod_alias.so
And then I modified the httpd.conf with the following:
<IfModule alias_module>
Alias /b /blog
ScriptAlias /cgi-bin/ "cgi-bin/"
</IfModule>
After I restarted the server and type the localhost/b in my address bar,however,it did not redirect to the localhost/blog.I don't konw why.Can you help me, Any help is greatly appreciated
Alias declarations aren't the same as redirects.
Alias /b /blog
tells Apache to make the files that exist on your file system under the path /blog (which doesn't mean much on Windows) available at the URL http://myserver.com/b, i.e. a request for http://myserver.com/b/something.html will try to return the content of the file /blog/something.html from your filesystem, failing if that file does not exist - the browser address bar will still say http://myserver.com/b/something.html.
It sounds like what you're after is
Redirect /b http://myserver.com/blog
In this case, a request for http://myserver.com/b/something.html will result in an HTTP redirect, the browser's address bar will change to say http://myserver.com/blog/something.html.
Of course, you then need to ensure that /blog resolves appropriately, which may require its own Alias if it's not under the DocumentRoot.
Alias /blog "C:/web/blog"
<Directory "C:/web/blog">
Order allow,deny
Allow from all
</Directory>

Apache 302 Redirect

I read this and here I am trying to do a 302 redirect using apache. I'm using the default Apache shipped with OSX 10.7:
Server version: Apache/2.2.21 (Unix)
Server built: Nov 15 2011 15:12:57
I tried to:
Create an .htaccess file and place inside:
Redirect temp /old.html http://localhost/new.html
or
Redirect 302 /old.html http://localhost/new.html
or
Redirect /old.html http://localhost/new.html
In httpd.conf modify the following section (note that in the conf file I see also LoadModule alias_module libexec/apache2/mod_alias.so):
<IfModule alias_module>
Redirect /old.html http://localhost/new.html
</IfModule>
I stopped/started several times Apache but with no luck. What's wrong?
Thanks!
EDIT: By not working I mean I get a 404!
Using Redirect directive requires that mod_alias is loaded.
Using Redirect directive inside .htaccess requires that at least FileInfo can be overridden. You need to add AllowOverride FileInfo in the appropriate section in httpd.conf (there could be more than one).
When you make changes to httpd.conf you need to restart Apache. This is probably the main issue.
Find the following line in your httpd.conf and change it, from
AllowOverride None
To
AllowOverride All

Apache rewrite rule

I want to redirect "http://localhost/b.html" --> "http://localhost/a.html"
I tried RewriteRule for that. But somehow it is not working for me.
I am using apache2 and my httpd.conf contains:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteRule ^/b.html$ http://localhost/a.html
When I tri "http://localhost/a.html" It shows me the web page. But when I triend "http://localhost/b.html" apache2/error_log says "file does not exist: b.html"
Does any setting missing to enable rewrite_module?
The problem is in your RewriteRule. this should work:
RewriteEngine On
RewriteRule ^/b.html$ /a.html [L]
the rule match (^b.html$) must not include the starting slash. (this works in .htaccess, but not in server config)
the rewrite target should be a relative URI if possible (i.e. on the same host)
the rule should end with a directive "what to do" - in this case [L]eave processing (no more rules will be processed)
Have you checked whether in your Apache configuration file (most likely httpd.conf) the directive for the Alias or VirtualHost section:
AllowOverride All
I had the same problem of modrewrite not working because I had it off:
AllowOverride None
Good luck.
Do you have it inside the virtualhost section?
<VirtualHost *:80>
RewriteEngine On
RewriteRule ^/b.html$ /a.html
</VirtualHost>
It works now. Had to do two things:
Change "AllowOverride None" in /etc/apache2/sites-available/default to "AllowOverride All".
Put the rewrite rule in /var/www/.htaccess instead of httpd.conf
I am not sure why it does not works in httpd.conf. But it works after doing the above two things.