DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 6.4 Limiting Upload Size

Problem

With more and more web hosting services allowing customers to upload documents, uploads may become too large. With a little creativity, you can put a limit on uploads by using the security capabilities of the server.

Solution

Assume you want to put a limit on uploads of ten thousand (10,000) bytes. Here's how you could do that for your /upload location:

SetEnvIf Content-Length "^[1-9][0-9]{4,}" upload_too_large=1
<Location /upload>
    Order Deny,Allow
    Deny from env=upload_too_large
    ErrorDocument 403 /cgi-bin/remap-403-to-413
</Location>

You can tailor the response by making the /cgi-bin/remap-403-to-413 script look something like this:

#! /usr/local/bin/perl
#
# Perl script to turn a 403 error into a 413 IFF
# the forbidden status is because the upload was
# too large.
#
if ($ENV{'upload_too_large'}) {
    #
    # Constipation!
    #
    print <<EOHT
Status: 413 Request Entity Too Large
Content-type: text/plain; charset=iso-8859-1
Content-length: 84

Sorry, but your upload file exceeds the limits
set forth in our terms and conditions.
EOHT
}
else {
    #
    # This is a legitimate "forbidden" error.
    #
    my $uri = $ENV{'REDIRECT_REQUEST_URI'};
    my $clength = 165 + length($uri);
    print <<EOHT
Status: 403 Forbidden
Content-type: text/html; charset=iso-8859-1
Content-length: $clength

<html>
 <head>
  <title>Forbidden</title>
 </head>
 <body>
  <h1>Forbidden</h1>
  <p>
  You don't have permission to access $uri
  on this server.
  </p>
 </body>
</html>
EOHT
}
exit(0);

Discussion

This script is invoked when a request results in a 403 Forbidden error (which is what the Deny directive causes if it's triggered). It checks to see if it's a real forbidden condition, or whether the upload file is too large, displaying an appropriate error page.

Note that both paths issue a Status CGI response header field; this is necessary to propagate the correct status back to the client. Without this, the status code would be 200 OK because the script would have been invoked successfully, which is hardly the appropriate status. An incorrect status code may cause the browser to report to the user that the file was uploaded successfully, which might generate confusion, as this may be in conflict with the message of the error page.

Actually there is a status value that corresponds to "you sent me something too large" (413), so we remap the Deny's 403 (Forbidden) status to it.

The same Content-length field is used to indicate the amount of data included in a POST request, such as from a web form submission, so be careful not to set your maximum too low or your forms may start getting this error!


See Also

    [ Team LiB ] Previous Section Next Section