gpt4 book ai didi

perl - 我如何在 Perl 中模拟 Web 服务器?

转载 作者:可可西里 更新时间:2023-11-01 15:26:51 24 4
gpt4 key购买 nike

我们的网络应用程序与几个我们无法影响的网络服务协同工作。在每个工作流程(使用 Selenium 测试)之后,都会发生对 Web 服务的 Hook 调用。我想模拟那个服务器。理想情况下,我需要一个可以随意启动和终止的 HTTP 服务器对象,以及一个 URL 调度程序,它会在调用时调用测试中的某些子例程。

到目前为止,我发现了 HTTP::Server::SimpleHTTP::Server::Brick,而且我发现后者更有吸引力。您还有其他内幕消息吗?

最佳答案

我结合使用了 HTTP::Daemon 和 Template::Toolkit 来做到这一点。

package Test::WebService;

use HTTP::Daemon;
use HTTP::Response;
use IO::File;
use Template;

our $PID = $$;

END { __PACKAGE__->StopWeb(); }

sub StartWeb : method {

my $self = shift;
my $port = shift;
my %actions = $_[0] && ref($_[0]) eq 'HASH' ? %{ $_[0] } : @_ %2 ? () : @_;

# Ignore CHLD
local $SIG{CHLD} = 'IGNORE';

# Fork
my $pid = fork();

if ( $pid == 0 )
{
# Create pid file
_createPid( "/tmp/httpd.pid" );

# Create server
eval
{
# Create socket
my $d = HTTP::Daemon->new
(
Listen => 1,
LocalPort => $port,
Reuse => 1,
) || die "Failed to bind socket";

# Listen for connections
while ( my $c = $d->accept )
{
# Process requests
while ( my $r = $c->get_request() )
{
if ( defined( my $tmpl = $actions{ $r->uri()->path() } ) )
{
eval
{
# Create template object
my $tt = Template->new( {ABSOLUTE => 1 } );

# Create response
my $rs = HTTP::Response->new('200');

# Process template
$tt->process
(
$tmpl,
$r->uri()->query_form_hash(),
sub { $rs->content( shift ) }
);

# Send response
$c->send_response( $rs );
};

if ($@)
{
$c->send_error('500', $@ );
}

}
else
{
$c->send_error('404', 'No Template Found');
}
}
}
};

if ($@)
{
# Remove pid file
unlink "/tmp/httpd.pid";

# die
die $@;
}

# Exit nicely
exit(0);
}

# Wait up to 5 seconds for server to start;
die "Failed to start http server" unless _waitpid( 5, "/tmp/httpd.pid" );

}

sub StopWeb {

# Only cleanup parent process.
if ( $PID && $PID == $$ )
{
if ( my $fh = IO::File->new( "/tmp/httpd.pid", 'r') )
{
# Get pid.
my $pid;
$fh->read( $pid, 16384 );
$pid =~ s/\D//g;

# Kill server
kill 4, $pid if $pid;
}
}
}

sub _createPid {

my $fh = IO::File->new( shift, 'w') || die "Couldn't create pid";
$fh->print("$$");
$fh->close();

return;
}

sub _waitpid {

my $secs = shift || 5;
my $file = shift || die "Missing pid file";

for( my $i=0; $i < $secs; $i++ )
{
return 1 if -e $file;
sleep 1;
}

return 0;
}

测试代码可以这样写:

#!/usr/bin/perl

use Test::More tests => 1;
use Test::WebService;

use MyApp;

Test::WebService->StartWeb( '8088', '/webservice/method' => 'my.tmpl' );

ok ( MyApp->methodThatCallsWebService(), 'yay!' );

1;

关于perl - 我如何在 Perl 中模拟 Web 服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1130099/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com