4

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}?

  • 2
    Out of curiosity, why would you need more than 255 characters?? – Chris S Nov 23 '11 at 01:00
  • I am passing a URL with a list of refiners into the application so that it can refine a large set of data. Normal queries don't come close to hitting that limit but occasionally someone wants to refine a ridiculous number of times. I could rewrite the application to submit a form with POST instead of parsing a URL but I'd rather just see if I can fix the URL length problem. – Jeremy Reimer Nov 23 '11 at 18:37
  • I love it when people go to the trouble of tracking you down (google+) for an answer, then don't bother to accept it. – h0tw1r3 Dec 07 '11 at 21:24

2 Answers2

2

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]
Ladadadada
  • 25,847
  • 7
  • 57
  • 90
  • This seems to be what I'm looking for, but I want to intercept URIs that are > 255 characters in **total**, not between slashes. What sort of regex would I use for this? – Jeremy Reimer Nov 23 '11 at 19:22
  • I'm not sure why this isn't working, but I'm still getting 403 Forbidden errors on any URLs that are > 255 characters long. I put the new rule above the other three lines like you said. – Jeremy Reimer Nov 23 '11 at 19:52
  • This is the part where mod_rewrite starts turning into voodoo for me. I have had some success at this point adding the `[PT]` option to the rewrite rule. – Ladadadada Nov 23 '11 at 19:59
0

The following works for me (tested in the default virtualhost on debian with apache 2.2.21).

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} (.{255}) [OR]
RewriteCond %{REQUEST_FILENAME} \.(html|nl)$ [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /index.cgi?$1 [L,QSA]
h0tw1r3
  • 2,746
  • 18
  • 17
  • This won't work. "not directory or not link or not file" will match everything. A directory is not a file (PASS on !-f), a link is not a directory (PASS on !-d), a file is not a link (PASS on !-l). If you add a file e.g. `robots.txt` and try to get it using `/robots.txt` your request will be rewritten to `/index.cgi?/robots.txt`. Those clauses must be ANDed together, not ORed. – Nicholas Shanks Jul 25 '13 at 07:46