I ran into an unexpected case of Apache giving me a 404 error instead of letting mod_rewrite handle the path, when one of the percent-encoded path parts was itself a HTTP URL.

For example:

GET /myfolder/http%3A%2F%2Flocalhost%2Fnotify HTTP/1.0

I have an extremely simple rule in the /myfolder/.htaccess file which sends everything that's not a file in /myfolder/ to a script. It works fine with other percent-encoded values, but in this case Apache never processes the RewriteRule from the .htaccess file. I can double-encode the value as a workaround, but it seems that Apache should still process the mod_rewrite phases. I intend the URL merely to be an input parameter to the script.

Here are the (ir)relevant mod_rewrite directives in /myfolder/.htaccess:

RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule .* ./script-the-world.php

The rewrite rules are NOT being processed. In the server configuration I've got RewriteLogLevel 5, etc., and tail -f /var/log/http/rewrite.log shows all my requests to /myfolder/ being rewritten... except for the one mentioned above. I mean to say that something internal is happening in the special case above, but I have no clue what it is. I'm hoping someone might know of another module that is interfering with what I'm trying to accomplish.

This is Apache 2.2.16.

  • What does your rule look like? – halfdan Apr 18 '11 at 16:32

You'll need to enable AllowEncodedSlashes, which will cause Apache to allow URLs with %2F and %5C in them, instead of throwing a 404. You will still, of course, have to make sure that your PHP script is handling the decoding of the URL correctly, as that's not Apache's duty.

| improve this answer | |

As this question is 9 years old now but still a current problem, I thought I'd give a more complete answer on how to solve it.

To enable %F2 and %5C in your paths without getting a 404 error, you'll need to add the following line to your apache2 config:

AllowEncodedSlashes NoDecode

From the Apache2.4 documentation:

The AllowEncodedSlashes directive allows URLs which contain encoded path separators (%2F for / and additionally %5C for \ on accordant systems) to be used in the path info.

With the default value, Off, such URLs are refused with a 404 (Not found) error.

With the value On, such URLs are accepted, and encoded slashes are decoded like all other encoded characters.

With the value NoDecode, such URLs are accepted, but encoded slashes are not decoded but left in their encoded state.

As NoDecode was introduced in 2.4, if you're still using Apache2.2, you can set the value to On instead. Be wary that their functionality is not the same. As the documentation states, NoDecode will not decode the string and leave it as is, while On will.

The bit nobody explained (to me at least) was where I should be applying this value. There are some references to the httpd.conf file, but good luck finding that file if you're running Apache2 on Debian. On Ubuntu, the file is called apache2.conf. And if you add the line to the apache2.conf file, you will probably not see much of a change.

The reason for that is that, as you may know, your config files will include sections per virtual host. And configs inside each of these <VirtualHost> section are applied after the corresponding sections outside the virtual host definition.

This allows virtual hosts to override the main server configuration. Which normally is good. Except in this context, where it will technically override the AllowEncodedSlashes directive (and set it back to the default Off), unless you explicitly state in each <VirtualHost> section what the value should be.

In summary, if you want to solve this problem, do the following (on Ubuntu at least):

  1. Go to /etc/apache2/sites-enabled
  2. Open up each file you find.
  3. Add AllowEncodedSlashes NoDecode inside each <VirtualHost> section that is relevant to you.
  4. Save the file.
  5. Restart apache2: sudo systemctl restart apache2.
| improve this answer | |
  • The filename apache2.conf is a Debian-ism, and like most of Debian's setup, is not standard Apache. – Michael Hampton Aug 13 at 23:48
  • Oh, I see, thanks! I had no idea, I've always used Ubuntu, and thought that was "normal". Will fix. – dearsina Aug 14 at 5:28
  • "this question is 11 years old" - actually, 9 years old. Note that the question is asking in the context of Apache 2.2 (9 yrs ago Apache 2.4 had not been released). NoDecode is an Apache 2.4 option. But you don't need the NoDecode option; On is sufficient. NoDecode changes the default behaviour, so this might not be desirable. Note that vHosts will only override this "(and set it back to Off)" if they have explicitly set it to Off - this doesn't happen by default. You probably wouldn't want to set this for the whole server anyway - unless you are serving just one site. – MrWhite Aug 16 at 22:18
  • @MrWhite, that's good to know. I have updated the answer. And I've adjusted the years from 11 to 9. ;-) – dearsina Aug 17 at 15:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.