How to reject requests before request body is sent?
How to reject requests before request body is sent?
am 24.11.2008 17:18:58 von Thomas Lindgren
------=_Part_157513_18214991.1227543538215
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hi all,
I'm using mod_perl2. I'd like to reject user requests, e.g., very large
PUTs, after examining headers and authorizing the user, but before the
request body is read. Quota checking could be an example of where this is
useful.
However, at this time, even if I return an error in the handler, it
(surprisingly) seems as if the request body still is uploaded. What to do?
Here is a boiled-down config, which just returns an error code after reading
the header. In the real code, I also examine the headers a bit before
deciding, but here I'm just interested in the case when the request is
rejected. The example below uses the HeaderParser hook, but the same things
seems to happen with a Fixup handler.
....
PerlHeaderParserHandler Test::Reject
The handler itself just returns an error code:
....
sub handler {
my $r = shift;
return Apache2::Const::HTTP_INSUFFICIENT_STORAGE;
}
Running a big PUT to $SERVER with curl transfers the body anyway (but then
returns the error):
# curl -o put.txt --basic --user a:b -T example.vmdk 'http://
$SERVER/test/foo.vmdk'
% Total % Received % Xferd Average Speed Time Time Time
Current
Dload Upload Total Spent Left
Speed
4 2743M 0 0 4 123M 0 9185k 0:05:05 0:00:13 0:04:52
10.4M^C
The only way to trigger an early close so far has been to die in the
handler, which confuses clients and so on.
The server could as a worst case alternative actually close the socket, but
that feels inelegant and hackish. So, my question to the esteemed list, how
should this sort of thing best be done? Have I forgotten something basic?
Should I return something else? Is there a more appropriate phase to do
this? Should I do it another way entirely?
Best,
Thomas
------=_Part_157513_18214991.1227543538215
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hi all,
I'm using mod_perl2. I'd like to reject user requests, e.g., very large PUTs, after examining headers and authorizing the user, but before the request body is read. Quota checking could be an example of where this is useful.
However, at this time, even if I return an error in the handler, it (surprisingly) seems as if the request body still is uploaded. What to do?
Here is a boiled-down config, which just returns an error code after reading the header. In the real code, I also examine the headers a bit before deciding, but here I'm just interested in the case when the request is rejected. The example below uses the HeaderParser hook, but the same things seems to happen with a Fixup handler.
...
<Location /test>
PerlHeaderParserHandler Test::Reject
</Location>
The handler itself just returns an error code:
....
sub handler {
my $r = shift;
return Apache2::Const::HTTP_INSUFFICIENT_STORAGE;
}
Running a big PUT to $SERVER with curl transfers the body anyway (but then returns the error):
# curl -o put.txt --basic --user a:b -T example.vmdk 'http://$SERVER/test/foo.vmdk'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
4 2743M 0 0 4 123M 0 9185k 0:05:05 0:00:13 0:04:52 10.4M^C
The only way to trigger an early close so far has been to die in the handler, which confuses clients and so on.
The server could as a worst case alternative actually close the socket, but that feels inelegant and hackish. So, my question to the esteemed list, how should this sort of thing best be done? Have I forgotten something basic? Should I return something else? Is there a more appropriate phase to do this? Should I do it another way entirely?
Best,
Thomas
------=_Part_157513_18214991.1227543538215--
Re: How to reject requests before request body is sent?
am 24.11.2008 21:55:53 von Adam Prime
Thomas Lindgren wrote:
> Hi all,
>
> I'm using mod_perl2. I'd like to reject user requests, e.g., very
> large PUTs, after examining headers and authorizing the user, but
> before the request body is read. Quota checking could be an example of
> where this is useful.
>
> However, at this time, even if I return an error in the handler, it
> (surprisingly) seems as if the request body still is uploaded. What to do?
>
>
> The only way to trigger an early close so far has been to die in the
> handler, which confuses clients and so on.
>
> The server could as a worst case alternative actually close the
> socket, but that feels inelegant and hackish. So, my question to the
> esteemed list, how should this sort of thing best be done? Have I
> forgotten something basic? Should I return something else? Is there a
> more appropriate phase to do this? Should I do it another way entirely?
This could be useful, but I think it's also pretty much impossible.
From what I understand, the entire request is read before any
processing is done at all, and definitely before the HeaderParserPhase
is executed, which is why you're seeing the behavior you describe.
The only other technique you might try would be an InputFilter, but I
have a feeling that even that wouldn't really stop the upload from
happening (ie the consumption of bandwidth). I think this has more to
do with TCP pipelining than it does with anything else, so it's actually
not "fixable" in the application at all.
Adam
Re: How to reject requests before request body is sent?
am 24.11.2008 22:12:53 von Fred Moyer
On Mon, Nov 24, 2008 at 8:18 AM, Thomas Lindgren
wrote:
> Hi all,
>
> I'm using mod_perl2. I'd like to reject user requests, e.g., very large
> PUTs, after examining headers and authorizing the user, but before the
> request body is read. Quota checking could be an example of where this is
> useful.
>
> However, at this time, even if I return an error in the handler, it
> (surprisingly) seems as if the request body still is uploaded. What to do?
I don't think that partial uploads are supported in the HTTP spec.
I'd suggest an inputfilter like Adam said, and maybe close the
connection if the request isn't what you want. A bit of a hack like
you said, but it should work if your client is aware of it.
>
> Here is a boiled-down config, which just returns an error code after reading
> the header. In the real code, I also examine the headers a bit before
> deciding, but here I'm just interested in the case when the request is
> rejected. The example below uses the HeaderParser hook, but the same things
> seems to happen with a Fixup handler.
>
> ...
>
> PerlHeaderParserHandler Test::Reject
>
>
> The handler itself just returns an error code:
>
> ...
> sub handler {
> my $r = shift;
> return Apache2::Const::HTTP_INSUFFICIENT_STORAGE;
> }
>
> Running a big PUT to $SERVER with curl transfers the body anyway (but then
> returns the error):
>
> # curl -o put.txt --basic --user a:b -T example.vmdk
> 'http://$SERVER/test/foo.vmdk'
> % Total % Received % Xferd Average Speed Time Time Time
> Current
> Dload Upload Total Spent Left
> Speed
> 4 2743M 0 0 4 123M 0 9185k 0:05:05 0:00:13 0:04:52
> 10.4M^C
>
> The only way to trigger an early close so far has been to die in the
> handler, which confuses clients and so on.
>
> The server could as a worst case alternative actually close the socket, but
> that feels inelegant and hackish. So, my question to the esteemed list, how
> should this sort of thing best be done? Have I forgotten something basic?
> Should I return something else? Is there a more appropriate phase to do
> this? Should I do it another way entirely?
>
> Best,
> Thomas
>
>
Re: How to reject requests before request body is sent?
am 25.11.2008 16:33:00 von Thomas Lindgren
------=_Part_10071_5679602.1227627180900
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
On Mon, Nov 24, 2008 at 9:55 PM, Adam Prime wrote:
> This could be useful, but I think it's also pretty much impossible. From
> what I understand, the entire request is read before any processing is done
> at all, and definitely before the HeaderParserPhase is executed, which is
> why you're seeing the behavior you describe.
>
Actually, I see log entries (not shown in the example) long before the big
example upload finishes, so the handlers appear to run before the request
completes. Furthermore, one description of RUN_ALL sort of hints that errors
should abort the cycle ("Mod_perl 2 users guide", p. 65), but, except if the
handler dies, it looks as if such errors are held back until the request has
been fully received. Too bad.
Thanks for the help guys, I'll see whether an input filter helps. Or perhaps
that socket hack.
Best,
Thomas
------=_Part_10071_5679602.1227627180900
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
On Mon, Nov 24, 2008 at 9:55 PM, Adam Prime
<> wrote:
This could be useful, but I think it's also pretty much impossible. From what I understand, the entire request is read before any processing is done at all, and definitely before the HeaderParserPhase is executed, which is why you're seeing the behavior you describe.
Actually, I see log entries (not shown in the example) long before the big example upload finishes, so the handlers appear to run before the request completes. Furthermore, one description of RUN_ALL sort of hints that errors should abort the cycle ("Mod_perl 2 users guide", p. 65), but, except if the handler dies, it looks as if such errors are held back until the request has been fully received. Too bad.
Thanks for the help guys, I'll see whether an input filter helps. Or perhaps that socket hack.
Best,
Thomas
------=_Part_10071_5679602.1227627180900--