Suggestion on perl handler to reject request with large content length

Suggestion on perl handler to reject request with large content length

am 19.11.2010 02:47:42 von mohitanchlia

I have been searching for an answer in httpd forum. But I think I need
to ask here:

I have a requirement to look at content length and if it is greatar
than desired size then return error message. So psuedo code is like:

if content_length > 32G
then
if url contains /abc/
then
echo "0|abc|Bad length" # pipe delimited format that some
clients api support
else if url contains /def/
echo "Bad request" # client supporting XML
fi
fi

I first thought of using LimitRequestBody but that didn't work for me.
So now I am thinking if using perl handlers.

P.S. Note: Our requests are mod-jk requests. So if content length
check succeeds then hand over the request to mod jk workers wihch then
send it to jboss app server.

I tried to write code but still unsure of few thing:

1. If I return HTTP_REQUEST_ENTITY_TOO_LARGE response then would it
still continue sending the request to mod_jk. Or would it be returned
back to the client? When does apache decide if request need to be
stopped and send back to the client.
2. Does my code look ok and something that will work? Can someone
please suggest?


This is my sample code

sub content_handler {
my $r = shift;
my $uri = $r->uri;
if ( $r->header_in("Content-length") lt 20000000) {
return Apache2::Const::OK; # Continue sending request to mod jk worker
}
$r->send_http_header;
if ($uri =~ /xml/){
$r->content_type("text/xml");
$r->print("File too large|Bye"); #Send pipe delimited back to the
client assuming it will not continue sending this request to mod_jk
worker
}else{
$r->content_type("text/plain");
$r->print ("Too Large, Bye!!");
#Send xml delimited back to the client assuming it will not continue
sending this request to mod_jk worker
}

return Apache2::Const::HTTP_REQUEST_ENTITY_TOO_LARGE; # Return back to client

Re: Suggestion on perl handler to reject request with large content length

am 19.11.2010 03:26:54 von markjreed

On Thu, Nov 18, 2010 at 8:47 PM, Mohit Anchlia wro=
te:
> I have a requirement to look at content length and if it is greatar
> than desired size then return error message. So psuedo code is like:

Easier solution: use LImitRequestBody, but have a perl handler that
sets a custom response text for 413's as appropriate.

something like:

sub handler {
my $r =3D shift;
if ($r->uri =3D~ /abc/) {

$r->custom_response

What if the request has no Content-Length: header at all? Do you let
it through then, no matter how big the body is?


> if content_length > 32G
> then
>  if url contains /abc/
>  then
>      echo "0|abc|Bad length" # pipe delimited format that =
some
> clients api support
>  else if url contains /def/
>      echo "Bad request" # cli=
ent supporting XML
>  fi
> fi

Yuck. I would move the logic into whatever handles the API calls
rather than duplicating the mapping from URI's to code in two places.
That's just asking for things to get out of synch.

> I first thought of using LimitRequestBody but that didn't work for me.
> So now I am thinking if using perl handlers.
>
> P.S. Note: Our requests are mod-jk requests. So if content length
> check succeeds then hand over the request to mod jk workers wihch then
> send it to jboss app server.
>
> I tried to write code but still unsure of few thing:
>
> 1. If I return  HTTP_REQUEST_ENTITY_TOO_LARGE response then would it
> still continue sending the request to mod_jk. Or would it be returned
> back to the client? When does apache decide if request need to be
> stopped and send back to the client.
> 2. Does my code look ok and something that will work? Can someone
> please suggest?
>
>
> This is my sample code
>
> sub content_handler {
>  my $r =3D shift;
>  my $uri =3D $r->uri;
>  if ( $r->header_in("Content-length") lt 20000000) {
>      return Apache2::Const::OK; # Continue sending request=
to mod jk worker
>  }
>  $r->send_http_header;
>  if ($uri =3D~ /xml/){
>     $r->content_type("text/xml");
>     $r->print("File too large|Bye"); #Send pipe delimited back =
to the
> client assuming it will not continue sending this request to mod_jk
> worker
>  }else{
>     $r->content_type("text/plain");
>     $r->print ("Too Large, Bye!!"=
);
> #Send xml delimited back to the client assuming it will not continue
> sending this request to mod_jk worker
>  }
>
>  return Apache2::Const::HTTP_REQUEST_ENTITY_TOO_LARGE; # Return back=
to client
>



--=20
Mark J. Reed

Re: Suggestion on perl handler to reject request with large content length

am 19.11.2010 03:33:32 von markjreed

Accidental tab strikes again. Anyway, the idea is to set up the
handler to run before LimitRequestBody, if possible. I'm not sure
what hook that is.

If you can do that, then something like this would work:

sub handler {
   my $r =3D shift;
   if ($r->uri =3D~ /abc/) {
$r->content_type('text/plain); # API will override this if it
gets past the LimitRequestBody
$r->custom_response(Apache2::Const::HTTP_REQUEST_ENTITY_TOO_ LARGE,
"File too large|Bye");
} elsif ($r->uri =3D~ /def/) {
$r->content_type('text/xml');
$r->custom_response(Apache2::Const::HTTP_REQUEST_ENTITY_TOO_ LARGE=
,"Bad
request
");
}
return Apache2::Const::OK
}

That way you don't have to duplicate the logic of the check yourself,
you're just arranging for a customized response when it fails.

--=20
Mark J. Reed

Re: Suggestion on perl handler to reject request with large content length

am 19.11.2010 21:33:38 von mohitanchlia

On Fri, Nov 19, 2010 at 9:59 AM, Mohit Anchlia wro=
te:
> On Thu, Nov 18, 2010 at 6:26 PM, Mark J. Reed wrote=
:
>> On Thu, Nov 18, 2010 at 8:47 PM, Mohit Anchlia =
wrote:
>>> I have a requirement to look at content length and if it is greatar
>>> than desired size then return error message. So psuedo code is like:
>>
>> Easier solution: use LImitRequestBody, but have a perl handler that
>> sets a custom response text for =A0413's as appropriate.
> Problem is that LimitRequestBody is not returning 413. Not sure why.
> If at all I get LimitRequesTBody to work then how will I bind this
> handler to the status code?
>>
>> something like:
>>
>> sub handler {
>> =A0 =A0my $r =3D shift;
>> =A0 =A0if ($r->uri =3D~ /abc/) {
>>
>> =A0 =A0$r->custom_response
>>
>> What if the request has no Content-Length: header at all? =A0Do you let
>> it through then, no matter how big the body is?
>>
>>
>>> if content_length > 32G
>>> then
>>> =A0if url contains /abc/
>>> =A0then
>>> =A0 =A0 =A0echo "0|abc|Bad length" # pipe delimited format that some
>>> clients api support
>>> =A0else if url contains /def/
>>> =A0 =A0 =A0echo "Bad request" # client sup=
porting XML
>>> =A0fi
>>> fi
>>
>> Yuck. =A0I would move the logic into whatever handles the API calls
>> rather than duplicating the mapping from URI's to code in two places.
>> That's just asking for things to get out of synch.
>
> I agree, but only problem is that the handler is in Jboss App. which
> means streams will have to pass from web server to our app server. I
> was trying to see if we can block right at the web server.
>>
>>> I first thought of using LimitRequestBody but that didn't work for me.
>>> So now I am thinking if using perl handlers.
>>>
>>> P.S. Note: Our requests are mod-jk requests. So if content length
>>> check succeeds then hand over the request to mod jk workers wihch then
>>> send it to jboss app server.
>>>
>>> I tried to write code but still unsure of few thing:
>>>
>>> 1. If I return =A0HTTP_REQUEST_ENTITY_TOO_LARGE response then would it
>>> still continue sending the request to mod_jk. Or would it be returned
>>> back to the client? When does apache decide if request need to be
>>> stopped and send back to the client.
>>> 2. Does my code look ok and something that will work? Can someone
>>> please suggest?
>>>
>>>
>>> This is my sample code
>>>
>>> sub content_handler {
>>> =A0my $r =3D shift;
>>> =A0my $uri =3D $r->uri;
>>> =A0if ( $r->header_in("Content-length") lt 20000000) {
>>> =A0 =A0 =A0return Apache2::Const::OK; # Continue sending request to mod=
jk worker
>>> =A0}
>>> =A0$r->send_http_header;
>>> =A0if ($uri =3D~ /xml/){
>>> =A0 =A0 $r->content_type("text/xml");
>>> =A0 =A0 $r->print("File too large|Bye"); #Send pipe delimited back to t=
he
>>> client assuming it will not continue sending this request to mod_jk
>>> worker
>>> =A0}else{
>>> =A0 =A0 $r->content_type("text/plain");
>>> =A0 =A0 $r->print ("Too Large, Bye!!");
>>> #Send xml delimited back to the client assuming it will not continue
>>> sending this request to mod_jk worker
>>> =A0}
>>>
>>> =A0return Apache2::Const::HTTP_REQUEST_ENTITY_TOO_LARGE; # Return back =
to client

I still need some suggestion on this question:

If I return HTTP_REQUEST_ENTITY_TOO_LARGE response then would PerlHandler
still continue sending the request to mod_jk. Or would it be returned
back to the client? When does apache decide if request need to be
stopped and send back to the client.

>>>
>>
>>
>>
>> --
>> Mark J. Reed
>>
>