How to change mod_rewrite to avoid {REQUEST_FILENAME} in order to get around 255 character URL limit

apache-2.2mod-rewrite

According to this answer: max length of url 257 characters for mod_rewrite? there is a maximum 255 character hard limit based on the file system for using mod_rewrite.

According to the accepted answer, there are two solutions:

  1. Change the URL format of your application to a max of 255 characters between each slash.
  2. Move the Rewrite rules into the apache virtual host config and remove the REQUEST_FILENAME.

I cannot use the first method, so I am trying to figure out the second.

I have put the Rewrite rules into the Apache virtual host config as requested. However I cannot figure out how to remove the REQUEST_FILENAME and still have my web application framework (Dragonfly) still work.

Here is the portion of the rewrite rules that I moved from .htaccess into the virtual host config file of Apache:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f [OR]

# if don't want Dragonfly to process html files comment
# out the line below (you may need to remove the [OR] above too).
RewriteCond %{REQUEST_FILENAME} \.(html|nl)$

# Main URL rewriting.
RewriteRule (.*) index.cgi?$1 [L,QSA]

I've tried removing {REQUEST_FILENAME} and it just breaks the framework in various ways. How do I rewrite this without using {REQUEST_FILENAME}?

Best Answer

The three lines below tell Apache to check the filesystem to see if the file exists.

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f [OR]

The first one means "if the URI is not a directory". The second one means "if the URI is not a link". The third one means "if the URI is not a file".

If you remove or comment out those lines, Apache will apply the rewrite below to every file that doesn't end in ".html" or ".nl" and will not check the file system to see if the file exists first.

There is a purpose to the three lines above. They are there so that if you add an actual file, directory or symlink into your document root and someone requests that file, directory or symlink, Apache will process it as normal and not do the rewrite. If you know that you will never add actual files into the document root then you can safely comment those out without any side effects.


A potentially better change would be to add a new rule above the three lines like this:

RewriteRule (.*[^/]{255}.*) index.cgi?$1 [L,QSA]

This will intercept any URIs that have a single string of more than 255 characters between slashes and send them straight to the rewrite without checking the filesystem. The [L] option ensures that Apache doesn't check any more rules if it matches this one. There is no danger of intercepting URIs that would have mapped to actual files because URIs that match this regex will not be valid file paths.

Update:

A regex that matches any URI that is at least 255 characters long.

RewriteRule (.{255}) index.cgi?$1 [L,QSA]
Related Topic