http://www.perlmonks.org?node_id=761270

dgaramond2 has asked for the wisdom of the Perl Monks concerning the following question:

I'm not sure yet if this is a bug with the module, so I'm posting the problem here first to confirm whether others are experiencing the same, and to gain some insights.

I'm writing an HTTPS daemon using HTTP::Daemon::SSL. It runs fine except when receiving POST requests with content larger than around 66-67k. The get_request() method won't return, as if it were trying to read more data, until the HTTP client breaks the connection and then get_request() will return the complete HTTP::Request object normally.

* GET and smaller POST requests are ok.

* The problem doesn't happen if I use HTTP instead (HTTP::Daemon).

* For the client I have tried LWP::UserAgent and wget, with the same result.

* I have tried localhost (127.0.0.1) as well as public address, with the same result.

* I have also tried using HTTP1/.0 instead of HTTP/1.1, with same result. To do this with LWP, you set env PERL_LWP_USE_HTTP_10=1. I'm not sure how to do this with wget though.

For those who want to reproduce the problem, here's how:

# server.pl
#!/usr/bin/perl -w
use strict;
use HTTP::Daemon::SSL;
use HTTP::Response;

my $server = HTTP::Daemon::SSL->new(
    LocalPort => 8010,
    Reuse => 1,
    Timeout => 180,
    SSL_key_file  => "server-key.pem",
    SSL_cert_file => "server.crt",
);

print "Server started on port 8010\n";
while (my $c = $server->accept) {
    print "Connection from ".$c->peerhost."\n";
    my $req = $c->get_request or next;
    print "Request dump: ".$req->as_string;
    my $resp = HTTP::Response->new(200);
    $resp->content("Thanks!");
    $c->send_response($resp);
}

Before running server.pl, create server-key.pem and server.crt:

$ openssl genrsa -out server-key.pem 1024
$ openssl req -new -key server-key.pem -out server.csr
$ openssl req -x509 -key server-key.pem -in server.csr -out server.crt

Ignore any questions about country code, etc and just press ENTER.

Then run server.pl, and then try to connect using wget with some data:

$ dd if=/dev/urandom of=post66k bs=1k count=66
$ dd if=/dev/urandom of=post67k bs=1k count=67
$ dd if=/dev/urandom of=post500k bs=1k count=500
$ wget -S -O- --no-check-certificate https://127.0.0.1:8010/; # normal
$ wget -S -O- --no-check-certificate https://127.0.0.1:8010/ --post-data 12345; # normal
$ wget -S -O- --no-check-certificate https://127.0.0.1:8010/ --post-file post66k; # normal
$ wget -S -O- --no-check-certificate https://127.0.0.1:8010/ --post-file post67k; # hangs
$ wget -S -O- --no-check-certificate https://127.0.0.1:8010/ --post-file post500k; # hangs

For the tests that hang, try pressing Ctrl-C to exit wget and the server will return the completed request normally.

Modules used are the most recent as of this writing: IO::Socket::SSL 1.24, HTTP::Daemon::SSL 1.04, LWP 5.826.

Tried on Debian Lenny on i686, which includes Perl 5.10.0. I have also tried this on Perl 5.8.8 on Debian Etch with same results.