Apache caching urls, RewriteEngine causing problems - apache

I was trying out the Apache Rewrite Engine, but was having problems because it cached it's responses. Now if I change the file, it does not do what the file says, but does what it did when I tried the same url before.
For example, I tried to type in
localhost/api
but I had not yet set a rule that would match that. The server gave me a 404 error. I tried to add a rule that would work with this url:
RewriteRule api/? api.php [L]
but it still gave me the same error. If I try an address like localhost/lapi which I didn't enter before I added the rule, it works. Is there a way to clear this cache and restart? I tried restarting apache using apachectl -k restart and apachectl -k graceful but I still had the same problem. Does anyone know how to fix this problem?

First of all, depending on the context of your rule, you may need a leading slash as in:
RewriteRule api/? /api.php [L]
Regarding the caching, do you have mod_cache enabled? If so, disable it and restart your server. mod_rewrite does not do any caching on its own. Also be sure to completely clear your browser cache and be aware that if you are not accessing your server over the same local network, there may be other caching taking place along the way.

This problem can also be caused by the MultiViews option, see Apache doc. Try omitting Option MultiViews from httpd.conf or add Options -MultiViews to .htaccess.
(The MultiViews option enables Apache to choose automaticaly between several versions of the file based on the file name extension and content preferences present in the HTTP request (i.e. something you probably don't want to happen). It can lead to this kind of bizzare failure when a rewrite rule just removes the script's extension.)

Related

mod_rewrite doesnt work if file with same name as argument exists

I'm experiencing some issues with mod_rewrite in htaccess.
Let's for instance say I request example.com/foo/, it works perfectly if I don't have a file starting with "foo.*" in the root directory.
Let's say I have news.php, sitemape.xml, style.css in root, I can't use /news/ or /sitemap/ or /style/ , it will give a 404 like /news.php/ etc.
Here's my rewrite string. It works locally with my Apache 2.2.22 but not at my web-host with the same Apache version.
RewriteRule ^([A-Za-z0-9]+)/?$ index.php?category=$1 [NC,L]
Anyone has a clue?
This sounds like Multiviews rearing its ugly head when its not wanted. It may be that your host automatically turns on the Multiviews option by default, and mod_negotiation then tries to "guess" what the request is for, and if it's close enough (like with /news/ and /news.php), it will automatically serve it, and disregard whatever mod_rewrite rules you may have.
Try turning off multiviews. You can do this in your htaccess file using the Options directive (assuming your host has allowed Options):
Options -Multiviews

Virtual Hosts (Apache) with mod_rewrite issues

I am trying to fix this whole day without success, so I hope someone might be able to help me. I have an app at http://localhost/, and it uses Pylons for the app I am hosting. In addition to that, I need to host a PHP/MySQL site, so I had to use Apache too.
My current setup is that I use haproxy with this config for the Apache backend:
backend apache
mode http
timeout connect 4000
timeout server 30000
timeout queue 60000
balance roundrobin
server app02-8002 localhost:8002 maxconn 1000
This is triggered by this:
acl image url_sub images
use_backend apache if image
So, when I open my IP/images, it will trigger that and open Apache then, with port 8002.
For Apache, I created virtual hosts, and this is the "image" one:
<VirtualHost *:8002>
ServerAdmin my#email.com
ServerName image
ServerAlias image
DocumentRoot /srv/www/image/public_html/
ErrorLog /srv/www/image/logs/error.log
CustomLog /srv/www/image/logs/access.log combined
</VirtualHost>
So, that all works nicely, when I type IP/images it open the /srv/www/image/public_html. But then the issues come. As I am using the image uploading script, it involves a lot of rewriting, so I had to enable that mod. This is the .htaccess which is located in the public_html/images folder (I somehow had to make this subfolder too, to "match" the URL with the actual location in the public_html.
SetEnv PHP_VER 5_3
RewriteEngine On
# You must define your installation directory and uncomment the line :
RewriteBase /images/
RewriteRule ^([a-zA-Z]+)\.(jpg|gif|png|wbmp)$ controller/Resizer.php?m=original&a=$1&e=$2 [L]
RewriteRule ^(icon|small|medium|square)\/([a-zA-Z]+)\.(jpg|gif|png|wbmp)$ controller/Resizer.php?m=$1&a=$2&e=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) application.php?request=$1 [L,QSA]
So, basically, this is somethow not working. I suppose there is a conflict between this virtual host, subdirectory, rewriting or something, but I can't seem to isolate it.
It is a bit confusing that when I open the IP/images/xxxx.jpg it opens the image, which is located in the public_html/images/upload/original folder, so the rewrite is working. The the other rules seem not to be working. All of the thumbnails and smaller versions are not rendering properly (with the icon, small, medium, square), so that makes the site quite unsusable.
Here is the link of the development server: http://localhost/images/
Thanks in advance for your time and help!
The first thing you should do is determine whether mod_rewrite is in fact part of the problem by accessing one of the failing URLs directly via its rewritten form and verifying that you get the expected result.
Indeed, the problem might simply be that the PHP script for the smaller resolutions "doesn't work" while it does for the original size ones. The first of the following URLs nicely served me an image; the second one is supposed to give me a smaller version of the same image, but served me an HTTP 500:
http://106.186.21.176/images/controller/Resizer.php?m=original&a=q&e=png
http://106.186.21.176/images/controller/Resizer.php?m=small&a=q&e=png
I got the same result (HTTP 500) for any of the smaller-size format names mentioned in your post, which matches your problem description.
Once you've verified that the script works as expected, it's likely that the problem is with mod_rewrite. If so, enable rewrite logging: use the RewriteLog directive to activate it, and RewriteLogLevel to control its verbosity. Especially at the higher log levels, it can give you very detailed information about exactly what it's doing. This should make the problem readily apparent from the logs.
Also, if possible, try to avoid configuring mod_rewrite rules in .htaccess files -- move them into your main server config file instead. The reason is explained on Apache mod_rewrite Technical Details, section "API phases":
Unbelievably mod_rewrite provides URL manipulations in per-directory context, i.e., within .htaccess files, although these are reached a very long time after the URLs have been translated to filenames. It has to be this way because .htaccess files live in the filesystem, so processing has already reached this stage. In other words: According to the API phases at this time it is too late for any URL manipulations. To overcome this chicken and egg problem mod_rewrite uses a trick: When you manipulate a URL/filename in per-directory context mod_rewrite first rewrites the filename back to its corresponding URL (which is usually impossible, but see the RewriteBase directive below for the trick to achieve this) and then initiates a new internal sub-request with the new URL. This restarts processing of the API phases.
Again mod_rewrite tries hard to make this complicated step totally transparent to the user, but you should remember here: While URL manipulations in per-server context are really fast and efficient, per-directory rewrites are slow and inefficient due to this chicken and egg problem. But on the other hand this is the only way mod_rewrite can provide (locally restricted) URL manipulations to the average user.
In general, not using .htaccess at all has the added advantage that you can tell Apache to not even bother and disable the functionality all together, which save Apache from having to scan each directory level it serves from for the .htaccess files.

Log of Apache rewrites

I'm getting a "webpage has a redirect loop" error. Most likely this is due to my Apache rewrite configuration. I've had these issues before, and find them hard to debug. Is there some sort of log that allows me to see what the request is being redirected to?
If not, how do you debug Apache rewrites in an efficient way?
If you are using newer Apache version (I'm testing it with 2.4), the RewriteLog directive has been replaced by the new per-module logging configuration (see apache doc).
Now you want to put the following line in your configuration:
LogLevel alert rewrite:trace3
and check your error log for the rewrite module messages.
tail -f error_log|fgrep '[rewrite:'
You can configure mod_rewrite's log file via the "RewriteLog" directive.
For example:
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
For more information, see: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritelog
One other link I find myself going back to is "crazy advanced mod_rewrite" -- lots of info there which you may want to stash away for future reference. It's at: http://www.askapache.com/htaccess/crazy-advanced-mod_rewrite-tutorial.html
See RewriteLog and RewriteLogLevel directives.

Apache mod_speling case insensitive URLs issue

I want to have case insensitive URLs using Apache's mod_speling module, but this is producing unwanted lists of "multiple options" whilst the Apache documention says
When set, this directive limits the action of the spelling correction to lower/upper case changes. Other potential corrections are not performed.
I'm testing this on an Apache 2.2.16 Unix fresh install but I'm still running into exact the same problems as submitted in 2008.
It's unexpected (and not wanted) behaviour when Apache lists a few "multiple choices" (status code 300) when the checkCaseOnly directive is on!
I have this in my httpd.conf:
CheckSpelling on
CheckCaseOnly on
First directive to use the mod_speling, second directive to limit only to case corrections
What am I doing wrong?
TLDR: CheckCaseOnly is broken due to a bug that has remained unfixed for over six years as of 10/2014.
I know this is an old question, but I just ran into the same issue. This update is to help others with the same issue.
The current answers to this question are incorrect, as the OP is using mod_speling correctly, but there is a bug.
https://issues.apache.org/bugzilla/show_bug.cgi?id=44221
The underlying issue is that the apache people are in disagreement over fixing this behavior because it changes the rest of the module. This has remained unfixed for something like 6 years.
To enable mod_speling (either by Location or VirtualHost) use the directive:
CheckSpelling On
If all you want is case insensitivity use:
CheckCaseOnly On
You also need to have RewriteEngine enabled:
RewriteEngine On
On Ubuntu 12.04 LTS using Apache 2.2, I did the following:
Create speling.conf in ${APACHE}/mods-available to provide the config options.
<IfModule mod_speling.c>
CheckSpelling On
CheckCaseOnly On
</IfModule>
Link speling.conf and speling.load into the enabled modules directory ${APACHE}/mods-enabled:
# cd ../mods-enabled
# ln -s ../mods-available/speling.conf speling.conf
# ln -s ../mods-available/speling.load speling.load
Restart the server.
# service restart apache2
After reading user1647075's answer about this being a known Apache bug that's unlikely to be fixed, I decided my best option was to hide the "multiple options" page from the user by updating my Apache config to show the 404 error page for 300 status codes:
ErrorDocument 300 /404.htm
Of course, you can also create a custom error page instead of reusing the 404 error page.
Hope this workaround helps.
Do you really want case insensitive URL?
Why not just force lowercase urls, like this?
RewriteEngine On
RewriteMap lc int:tolower
RewriteRule (.*) ${lc:$1} [R]
Have a look at http://www.issociate.de/board/post/265865/make_URL

mod_rewrite 'add path info postfix:'

Why is my mod_rewrite doing this?
add path info postfix: /home/mobelluk/public_html/about.php -> /home/mobelluk/public_html/about.php/
which results in an unwanted trailing slash on EVERYTHING.
I have disabled all my .htaccess rules so they're out of the equation.
apparently there's been an issue with mod_rewrite re-appending post-fix part in certain cases
https://issues.apache.org/bugzilla/show_bug.cgi?id=38642
The problem:
If multiple RewriteRules within a .htaccess file match, unwanted copies of PATH_INFO may accumulate at the end of the URI.
If you are on Apache 2.2.12 or later, you can use the DPI flag to prevent this
http://httpd.apache.org/docs/2.2/rewrite/flags.html
In searching for "add path info postfix", this question comes up first and while it eventually did solve my problem, it took me almost 2 hours to understand what was going on.
In working on a site, I needed this rewrite:
/resources/band/ -> resources.html?section=band
Accomplished with this mod_rewrite:
RewriteRule ^resources/(.*)/$ resources.html?section=$1 [L]
Changing that to [DPI] did nothing... The code on my resources.html page was 100% for sure being called but the argument of section=band was not being sent to it.
Get this... in case you find Apache's documentation impossible to read, Multiviews is the problem. When the browser sees that multiviews is on the server sees /resources/band/ and say "Oh, I'm so smart, I know what that means!" and redirects:
/resources/band/ -> /resources.html/band/
True story! I changed the +Multiviews to -Multiviews on the virtual host - problem instantly solved.
Is it possible the new server has mod_dir loaded, with DirectorySlash On where the old one did not and that is leading to this problem?
(Note that DirectorySlash On is the default if mod_dir is loaded and nothing is overriding it)
I solved this issue by disabling MultiViews in my virtual host Options configuration. I was rewriting something similar to below:
Desired rewrite:
/dir/ -> /dir.html
Actual translations:
/dir/ -> /dir.html (MultiViews)
/dir.html -> /dir.html/ (mod_rewrite: 404, didn't exist)
Disabling MultiViews kept the initial translation from taking place. I could have probably adjusted the rewrite rule to compensate for this, but I wasn't using MultiViews for anything else anyway.
The following post tipped me off on this issue:
https://velenux.wordpress.com/2012/07/17/apache-mod_rewrite-multiple-add-path-info-postfix/#comment-1476