Perl 编程/HTTP::Engine
HTTP::Engine由 Kazuhiro Osawa (yappo) 创建。它是一个针对应用程序开发人员的通用接口,可以轻松地在各种服务器配置下部署,包括 CGI、FastCGI、mod_perl以及独立的纯 Perl HTTP 服务器。然而,它不是一个完整的 Web 应用程序框架,但基于它编写框架会很容易。
例如,这是一个简单的应用程序,它只输出“Hello World”
# MyApp.pm
package MyApp;
use strict;
use warnings;
use HTTP::Engine::Response;
sub run {
my ($class, $request) = @_;
my $response = HTTP::Engine::Response->new;
$response->body("Hello World");
$response->status(200);
return $response;
}
1;
这run方法在这里接受一个HTTP::Engine::Request实例作为输入,并返回一个HTTP::Engine::Response对象作为输出。这个子程序是来自 HTTP 服务器的第一个处理程序。在一个更复杂的应用程序中,它通常只是根据 URI 或参数将实际工作分派给其他子程序。
要将其部署为 CGI 脚本,您需要编写一个“hello.cgi”就像这样
#!/usr/bin/perl use MyApp; use HTTP::Engine; HTTP::Engine->new( interface => { module => 'CGI', request_handler => sub { MyApp->run(@_); } } )->run;
如果有一天,你需要在这个应用程序下部署mod_perl环境,你可以编写一个MyApp::ModPerl处理程序类,代码如下
package MyApp::ModPerl; use Any::Moose; extends 'HTTP::Engine::Interface::ModPerl'; use MyApp; use HTTP::Engine; sub create_engine { my($class, $r, $context_key) = @_; HTTP::Engine->new( interface => { module => "ModPerl", request_handler => sub { MyApp->run(@_); } } ); } __PACKAGE__->meta->make_immutable; no Any::Moose; 1;
您的核心应用程序代码不需要修改,只要您只使用HTTP::Engine::*类来构建您的响应。
您可能会质疑为什么费心建立一个抽象层,而不是直接选择一个好的部署环境。一个很好的答案是,没有这个抽象层,可能很难测试应用程序。
如果您的首选部署配置类似于mod_perl,那么您的测试程序将需要启动一个带有mod_perl.so加载的 apache httpd,然后尝试使用Test::WWW::Mechanize与它通信。这也可以,但太麻烦了。
HTTP::Engine附带了一个专门的测试接口,可以轻松完成此操作。要测试我们的“Hello World”应用程序是否正常工作,您可以编写一个像这样的测试程序
# test.pl use strict; use warnings; use Test::More tests => 1; use MyApp; use HTTP::Engine; use HTTP::Request; use HTTP::Response; my $engine = HTTP::Engine->new( interface => { module => 'Test', request_handler => sub { return MyApp->run(@_); } } ); my $response = $engine->run( HTTP::Request->new(GET => 'https://127.0.0.1/'), env => \%ENV, connection_info => { request_uri => "/" } ); is($response->content, "Hello World", "The application does output Hello World!");
如果比较了$engine对象的构造语句,您会发现唯一的区别是“module”值。这个“Test”模块使$engine对象成为一个完全模拟的环境,它基本上只是准备了所有需要的环境变量,并执行您的应用程序代码。
这使得它非常轻量级,易于运行和编写测试程序。然后,您可以像编写单元测试一样编写功能测试。