我在这个标题为:Perl HTTP服务器的 SO问答上找到了以下Perl代码.特别是这个答案.这是我修改过的代码:
#!/usr/bin/perl use strict; use warnings; use CGI qw/ :standard /; use Data::Dumper; use HTTP::Daemon; use HTTP::Response; use HTTP::Status; use POSIX qw/ WNOHANG /; use constant HOSTNAME => qx{hostname}; my %O = ( 'listen-host' => '127.0.0.1', 'listen-port' => 8080, 'listen-clients' => 30, 'listen-max-req-per-child' => 100, ); my $d = HTTP::Daemon->new( LocalAddr => $O{'listen-host'}, LocalPort => $O{'listen-port'}, Reuse => 1, ) or die "Can't start http listener at $O{'listen-host'}:$O{'listen-port'}"; print "Started HTTP listener at " . $d->url . "\n"; my %chld; if ($O{'listen-clients'}) { $SIG{CHLD} = sub { # checkout finished children while ((my $kid = waitpid(-1, WNOHANG)) > 0) { delete $chld{$kid}; } }; } while (1) { if ($O{'listen-clients'}) { # prefork all at once for (scalar(keys %chld) .. $O{'listen-clients'} - 1 ) { my $pid = fork; if (!defined $pid) { # error die "Can't fork for http child $_: $!"; } if ($pid) { # parent $chld{$pid} = 1; } else { # child $_ = 'DEFAULT' for @SIG{qw/ INT TERM CHLD /}; http_child($d); exit; } } sleep 1; } else { http_child($d); } } sub http_child { my $d = shift; my $i; my $css = <accept or last; my $r = $c->get_request(1) or last; $c->autoflush(1); print sprintf("[%s] %s %s\n", $c->peerhost, $r->method, $r->uri->as_string); my %FORM = $r->uri->query_form(); if ($r->uri->path eq '/') { _http_response($c, { content_type => 'text/html' }, start_html( -title => HOSTNAME, -encoding => 'utf-8', -style => { -code => $css }, ), p('Here are all input parameters:'), pre(Data::Dumper->Dump([\%FORM],['FORM'])), (map { p(a({ href => $_->[0] }, $_->[1])) } ['/', 'Home'], ['/ping', 'Ping the simple text/plain content'], ['/error', 'Sample error page'], ['/other', 'Sample not found page'], ), end_html(), ) } elsif ($r->uri->path eq '/ping') { _http_response($c, { content_type => 'text/plain' }, 1); } elsif ($r->uri->path eq '/error') {a my $error = 'AAAAAAAAA! My server error!'; _http_error($c, RC_INTERNAL_SERVER_ERROR, $error); die $error; } elsif ($r->method eq 'POST' and $r->uri->path eq '/formdata') { #_http_response($c, { content_type => 'text/plain' }, 1); print "--> begin form data <--\n"; _http_response($c, { content_type => 'text/html' }, start_html( -title => HOSTNAME, -encoding => 'utf-8', -style => { -code => $css }, ), p('Here are all the input parameters:'), pre(Data::Dumper->Dump([\%FORM],['FORM'])), end_html(), ); print Data::Dumper->Dump([$r], [qw(r)]); print "--> end form data <--\n"; } else { _http_error($c, RC_NOT_FOUND); } $c->close(); undef $c; } } sub _http_error { my ($c, $code, $msg) = @_; $c->send_error($code, $msg); } sub _http_response { my $c = shift; my $options = shift; $c->send_response( HTTP::Response->new( RC_OK, undef, [ 'Content-Type' => $options->{content_type}, 'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', 'Pragma' => 'no-cache', 'Expires' => 'Thu, 01 Dec 1994 16:00:00 GMT', ], join("\n", @_), ) ); }
我正在使用此curl
命令连接到服务器.
$ curl -X POST -H "Content-Type: multipart/form-data; \ boundary=----------------------------4ebf00fbcf09" \ --data-binary @test.txt \ http://localhost:8080/formdata?arg1=blah1\&arg2=blah2
随着这个测试文件.
$ cat test.txt This is some test text in a file.
当我运行它时返回以下内容:
greeneggs.bubba.net Here are all the input parameters:
$FORM = { 'arg2' => 'blah2', 'arg1' => 'blah1' };
如何处理服务器端多数据表单中的数据?我认为数据可以通过request($r
)访问,但是当我使用Data :: Dumper进行分析时,我看不到任何类似于数据的内容.
通过curl
命令连接到http服务器后从http服务器输出:
[127.0.0.1] POST /formdata?arg1=blah1&arg2=blah2 --> begin form data <-- $r = bless( { '_protocol' => 'HTTP/1.1', '_content' => '', '_uri' => bless( do{\(my $o = '/formdata?arg1=blah1&arg2=blah2')}, 'URI::http' ), '_headers' => bless( { 'user-agent' => 'curl/7.29.0', 'content-type' => 'multipart/form-data; boundary=----------------------------4ebf00fbcf09', 'accept' => '*/*', 'content-length' => '34', 'host' => 'localhost:8080' }, 'HTTP::Headers' ), '_method' => 'POST' }, 'HTTP::Request' ); --> end form data <--
我错过了什么?