Hi,

according to RFC2616 (HTTP/1.1) section 4.4 it is valid to do POST method
without specifying Content-Length. Mobile phone SonyEricsson P900 sends such
requests to its specified WAP proxy (behaving in HTTP way - I assume a bug):
        http://www.jankratochvil.net/priv/SonyEricssonP900.HTTPrequest.gz

Unfortunately no httpd/apache or squid versions support such requests.
* httpd assumes no body at all and tries to interpret the message body as
  another HTTP request.
* squid complains with 411 (length required)

I tried to workaround it by the attached mod_perl input handler but it has some
issues. I expect httpd C core should be fixed instead. Will be the patch
accepted? Is anyone willing to patch it? :-)


Regards,
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/
# $Id: ApacheInputFilterAddContentLength.pm,v 1.3 2004/08/07 06:48:02 short Exp $

package MMS2::ApacheInputFilterAddContentLength;
use strict;
use warnings;

use base qw(Apache::Filter);

use APR::Brigade ();
use APR::Bucket ();
use Apache::Const;
use APR::Const;
#use Data::Dumper;


# Do not:
# as it will read the input line-by-line [check/FIXME:] with stucking at the end.
#sub handler:FilterConnectionHandler
#{
#my($f)[EMAIL PROTECTED];
#
#        warn "in";
#        my $buf;
#        while ($f->read($buf,0x1000)) {
#                warn $buf;
#                $f->print($buf);
#                }
#        Apache::OK;
#}


sub handler:FilterConnectionHandler
{
my($f,$bb,$mode,$block,$readbytes)[EMAIL PROTECTED];

        my $ctx=$f->ctx();
        $ctx->{"data"}="" if !exists $ctx->{"data"};

        my $got;
        if (!$ctx->{"done"}) {
                $ctx->{"done"}=1;

                # Prevent calling &get_brigade for the second time as it would get 
stuck.
#               my $rv=$f->next->get_brigade($bb,$mode,$block,$readbytes);
                my 
$rv=$f->next->get_brigade($bb,Apache::MODE_READBYTES,APR::BLOCK_READ,0x1000000);
                return $rv if $rv!=APR::SUCCESS;

                # Do not: $bb->flatten($data)
                # as &flatten is from mod_perl-1.99_13 while Fedora Core 2 has 
mod_perl-1.99_12.
                for (my $b=$bb->first;$b;$b=$bb->next($b)) {
                        my $data;
                        $b->read($data);
                        $ctx->{"data"}.=$data if length $data;
                        $b->remove();
                        }
                # Do not: $bb->cleanup();
                # as &cleanup is from mod_perl-1.99_15 while Fedora Core 2 has 
mod_perl-1.99_12.

                if ($ctx->{"data"}=~/^(.*?\r\n)\r\n(.*)$/s) {
                        my($headers,$body)=($1,$2);
                        $headers=~/^Content-Length\b/im
                                        or $headers.="Content-Length: 
".length($body)."\r\n";
                        $ctx->{"data"}=$headers."\r\n".$body;
                        die "Invalid Transfer-Encoding $1" if 
$headers=~/^Transfer-Encoding\b([^\r\n]*)/im;
#                       warn Dumper \%headers;
#                       warn Dumper "data=",$ctx->{"data"};
                        }
                }

        my $result;
        # FIXME: Check $mode here.
        ($result,$ctx->{"data"})=split /\r\n/,$ctx->{"data"},2;
        if (defined $result) {
                $result.="\r\n" if defined $ctx->{"data"};
                my $bn=APR::Bucket->new($result);
                $bb->insert_tail($bn);
                }
#       warn Dumper "result=",$result;

        $f->ctx($ctx);
        Apache::OK;
}

1;

Reply via email to