I am trying to write a mod_perl handler to take POST requests which have
some parameters encoded in the url string, and a body that needs to be
saved to a file. It is not like a conventional file upload from a form.
I want to implement a limit on the size of the body that can be
uploaded. However, I do not want to return a failure to the client in
that case, rather I want to process the header information (saving it to
a database), but just not save the file. The problem I am having is that
I cannot figure out how to throw away the data if it is above a certain
size limit, without loading all the data.
I have a module registered as a PerlResponseHander, with code somewhat
like
my $contentLimit = 104857600;
sub handler {
my $r = shift;
my $req = Apache2::Request->new($r);
my $contentLength = $r->headers_in->{'Content-Length'};
# figure out if we have been sent too much stuff
if ($contentLength > $contentLimit) {
&r->log_error($r, "not saving because: " . $req->body_status());
} else {
&saveZipData($r, $outFile);
}
# write data from headers to database
&persistHeaderInfo(...);
# return ok
return Apache2::Const::OK;
}
sub saveZipData {
my ($r, $outFile) = @_;
my $buffer;
my $data;
open OUT, ">$outFile" or die "Could not open $outFile for output:
$!";
binmode OUT;
while ($r->read($buffer, 4092)) {
$data .= $buffer;
print OUT $buffer;
}
close OUT;
}
I find that the very large file gets completely loaded, just not saved
to disk. What I want to happen in the case of a large upload is for the
file not to be uploaded, and just the headers processed and the database
updated. E.g. so that that response time for the client with a very
large upload is short.
I have tried POST_MAX on the Apache2::Request creation, but that just
appears to write an error message.
I have tried reading the documentation on filters. Do I need to make an
input filter to throw away the data if it is larger than a certain size?
If so, how? Should I be saving the data to file in a filter or is it ok
to do it in a PerlResponseHandler?
There are also calls on the RequestRec object like
discard_request_body(), but these don't seem to alter the behavior that
I see.
Any help would be much appreciated
Cheers
Matt