I ran into an "interesting" bug in CGI.pm today, and figured I'd post here as this is a potential problem in Apache 2/modperl 2 setups.

I have a form of application server that runs as a CGI in a modperl 2 system, where the client submits a request in XML format, using a POST request.

Last night an error was reported - looking in the log I saw that the data from the POST had been truncated. After a bit of searching, including using tcpdump to verify that the data was really being sent correctly, I found a post on the modperl mailing list which pointed in the right direction.

It appears that in some circumstances apache 2/modperl 2 don't read the full POST in a single call.

CGI.pm has the following call to read the POST:

sub read_from_client { my($self, $buff, $len, $offset) = @_; local $^W=0; # prevent a warning return $MOD_PERL ? $self->r->read($$buff, $len, $offset) : read(\*STDIN, $$buff, $len, $offset); }
The problem here is that $self->r->read() doesn't necessary read $len bytes, and CGI.pm doesn't check this.

My fix, based on a fix posted by Stas Bekman in the modperl list, is to simply call read_from_client() in a loop. The patch to CGI.pm (version 3.01) looks like this:

*** CGI.pm~ 2003-12-12 15:09:45.000000000 -0800 --- CGI.pm 2003-12-12 15:12:29.000000000 -0800 *************** *** 551,558 **** } if ($meth eq 'POST') { ! $self->read_from_client(\$query_string,$content_length,0) ! if $content_length > 0; # Some people want to have their cake and eat it too! # Uncomment this line to have the contents of the query string # APPENDED to the POST data. --- 551,565 ---- } if ($meth eq 'POST') { ! if($content_length > 0) { ! my $len = $content_length; ! while ($len > 0) { ! my $data = ''; ! my $read = $self->read_from_client(\$data,$content_length,0); ! $len -= $read; ! $query_string .= $data if $read > 0; ! } ! } # Some people want to have their cake and eat it too! # Uncomment this line to have the contents of the query string # APPENDED to the POST data.
Michael

In reply to CGI.pm bug in Apache 2/mod-perl 2 setup by mpeppler

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.