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:///'),
env => \%ENV,
connection_info => {
request_uri => "/"
}
);
is($response->content, "Hello World", "The application does output Hello World!");
如果比較了$engine物件的構造語句,您會發現唯一的區別是“module”值。這個“Test”模組使$engine物件成為一個完全模擬的環境,它基本上只是準備了所有需要的環境變數,並執行您的應用程式程式碼。
這使得它非常輕量級,易於執行和編寫測試程式。然後,您可以像編寫單元測試一樣編寫功能測試。