HTTP ::守护进程和线程

时间:2011-01-27 10:37:15

标签: perl http

我在Windows XP和ActiveState ActivePerl 5.8上有以下代码。

它可能有什么问题?为什么不起作用?

我尝试将其设置为我的IE的代理,但是当我从IE连接到某些URL时,没有任何反应。代码进入线程函数,没有任何反应。

use HTTP::Daemon;
use threads;
use HTTP::Status;
use LWP::UserAgent;

my $webServer;
my $d = HTTP::Daemon->new(
    LocalAddr => '127.0.0.1',
    LocalPort => 80,
    Listen    => 20
) || die;

print "Web Server started!\n";
print "Server Address: ", $d->sockhost(), "\n";
print "Server Port: ",    $d->sockport(), "\n";

while (my $c = $d->accept) {
    threads->create(\&process_one_req, $c)->detach();
}

sub process_one_req {
    STDOUT->autoflush(1);
    my $c = shift;
    while (my $r = $c->get_request) {
        if ($r->method eq "GET") {
            print "Session info\n", $r->header('Host');
            my $ua       = LWP::UserAgent->new;
            my $response = $ua->request($r);
            $c->send_response($response);

        } else {
            $c->send_error(RC_FORBIDDEN);
        }

    }
    $c->close;
    undef($c);
}

2 个答案:

答案 0 :(得分:0)

我在LWP :: UserAgent-> new之前的代码中添加了以下行,它似乎对我有用(在linux中)。

$r->uri("http://" . $r->header('Host') . "/" . $r->uri());

您从原始请求的HTTP :: Request对象获得的uri没有主机名。所以添加它使它成为一个绝对的uri。测试如下:

$ curl -D - -o /dev/null -s -H 'Host: www.yahoo.com' http://localhost:8080/
HTTP/1.1 200 OK
Date: Thu, 27 Jan 2011 12:59:56 GMT
Server: libwww-perl-daemon/5.827
Cache-Control: private
Connection: close
Date: Thu, 27 Jan 2011 12:57:15 GMT
Age: 0
---snip--

更新:看起来我完全错了。我不需要对URI对象进行更改。你的原始代码对我有用,就像在Linux中一样

答案 1 :(得分:0)

如果我没记错的话,这是因为Windows中的线程模型,除非特别要求,否则不会在进程之间传递文件句柄。 This PerlMonks post似乎揭示了潜在的问题,并可能导致一种适合您的方法(我想你可能能够在客户端连接的文件描述符上调用windows API以允许访问它在产生的线程中。)

Windows上的Perl线程通常会让我头疼,而在UNIX列表系统上,我发现它们很容易处理。然后,我想象一下如何正确使用分叉进程来模拟系统上的线程,该系统只支持线程,而不是分叉会让大多数人受到伤害。