Mod_parrot
Оригинал : http://www.perl.com/pub/a/2004/12/22/mod_parrot.html
Как известно , mod_perl - средство для написания веб-приложений и расширения
возможностей апача . В новой 6-й версии перла , которая еще не доведена до конца ,
появляется новый енжин - Parrot .
Модуль mod_parrot также , как и mod_perl ,
имеет прямой доступ к API и дает возможность писать собственные хэндлеры.
Parrot - это оптимизированная виртуальная машина ,
выполняющая откомпилированный байт-код .
Существуют отдельные виртуальные машины также под питона,пхп,раби(или руби ?).
Получается 4 разных языка , и задача parrot - обьединить их в общем суб-языке.
Parrot включает 3 ипостаси :
собственно сам байткод
PASM - ассемблер , который и генерит этот байткод
PIR: Parrot Intermediate Representation (PIR) - более высокоуровневая языковая
надстройка над PASM
Mod_parrot был сотворен Bjorn Hansen , Robert Spier , Kevin Falconeв 2002 году .
Если рассматривать основные фичи mod_perl , то они имеют меньше отношения
к выводу контента
и больше к таким вещам , как аутентификация и фильтры , и все это на перле .
Parrot использует собственные обьекты для доступа к API .
Апач , кроме перла , понимает также пхп , питон , раби и даже лисп .
Для каждого из этих языков
существует свой собственный модуль . В parrot все эти модули сведены воедино .
NCI (native call interface) - механизм доступа к Apache API ,
каждая из которых представляет из себя враппер , или набор си-шных макросов ,
которые вкомпилированы в mod_perl .
В parrot NCI переписан , теперь он не привязан к этим врапперам и позволяет вызвать
произвольную си-шную функцию без написания собственно самого си-кода .
Вот как из mod_parrot делается sys call getpid():
.sub _main
# load libc.so, where getpid() is defined, and assign it to $P0
$P0 = loadlib '/lib/libc.so.6'
# find the function in the library and assign it to $P1
# 'iv' means that getpid() returns an integer and takes no arguments
$P1 = dlfunc $P0, 'getpid', 'iv'
# call getpid() and place result in $I0
$I0 = $P1( )
# print the PID
print $I0
print "\n"
.end
Собственно сами апач-API-функции находятся в httpd . Пэррот может вызывать
их и отсюда тоже .Базовым классом для пэррот является Apache::RequestRec.
Пример вызова функции ap_rputs(аналг $r->puts в mod_perl)
.sub puts method, prototyped
.param string data
.local pmc r
.local pmc ap_rputs
.local int offset
classoffset offset, self, 'Apache::RequestRec'
getattribute r, self, offset
# find NCI object for ap_rputs
find_global ap_rputs, 'Apache::NCI', 'ap_rputs'
# use NCI to call out to Apache's ap_rputs
ap_rputs( data, r )
.end
Загрузить parrot можно по адресу http://www.smashing.org/mod_parrot
Необходимый минимум :
Apache 2.0.50 or later
Perl 5.6.0 or later (for configuration only)
Apache::Test 1.13 or later (for the test suite)
Пример написания "Hello World," на PIR :
# this namespace is used to identify the handler
.namespace [ 'HelloWorld' ]
# the actual handler
.sub _handler
# our Apache::RequestRec object
.local pmc r
# this will contain Apache constants
.local pmc ap_constants
# instantiate the Apache::RequestRec object
find_type $I0, 'Apache::RequestRec'
r = new $I0
# who should we say hello to?
$S0 = r.'args'( )
$I0 = length $S0
if $I0 > 0 goto say_hello
$S0 = 'world'
say_hello:
# call the puts method to send some output
$S1 = 'Hello ' . $S0
r.'puts'( $S1 )
# tell Apache that we're finished with this phase
find_global ap_constants, 'Apache::Constants', 'ap_constants'
$I0 = ap_constants['OK']
.pcc_begin_return
.return $I0
.pcc_end_return
.end
Вначале мы прописываем нэймспэйс . Далее идет собственно _handler .
Он начинается с обьявления локальных переменных .
Ap_constants дает доступ к внутренним переменным самого апача -
OK и DECLINED.
Код проверяет querystring , используя метод Apache::RequestRec->args
и иприсваивает ее значение строке $S0 .
Далее вызывается Apache::RequestRec->puts для вывода контента .
По умолчанию тип контента text/html.
После этого мы говорим апачу - ОК - с помощью ap_constants,
и выходим из хэндлера .
Для компиляции этого хэндлера в байткод , сохраняем файл с расширением
.imc и выполняем :
parrot -o HelloWorld.pbc HelloWorld.imc
Как инициализировать mod_parrot и заодно наш хэндлер:
ParrotInit /path/to/lib/ModParrot/init.pbc
ParrotLoad /path/to/lib/Apache/RequestRec.pbc
ParrotLoad /path/to/lib/Apache/Constants.pbc
ParrotLoad /path/to/HelloWorld.pbc
Для постоянной загрузки нашего хэндлера надо прописать в httpd.conf:
SetHandler parrot-code
ParrotHandler HelloWorld
Ниже дан пример хэндлера аутентификации для зашиты private-директории .
В качестве критерия доступа служит пароль "squawk." . PIR-код :
# this namespace is used to identify the handler
.namespace [ 'TestAuthHandler']
# the actual handler
.sub _handler
# our Apache::RequestRec object
.local pmc r
.local string pw
.local int status
# this will contain Apache constants
.local pmc ap_constants
find_global ap_constants, 'Apache::Constants', 'ap_constants'
# instantiate the Apache::RequestRec object
find_type $I0, 'Apache::RequestRec'
r = new $I0
# check the password, ignoring the username
(status, pw) = r.'get_basic_auth_pw'( )
if pw != 'squawk' goto auth_failure
$I0 = ap_constants['OK']
goto auth_return_status
# authentication failed
auth_failure:
$I0 = ap_constants['HTTP_UNAUTHORIZED']
goto auth_return_status
# return our status code
auth_return_status:
.pcc_begin_return
.return $I0
.pcc_end_return
.end
Пропишем в httpd.conf:
ParrotAuthenHandler TestAuthHandler
AuthType Basic
AuthName Private
Require valid-user
А вот пример "Hello,world" , написанный на 6-м перле :
use Apache::Constants ':common';
use Apache::RequestRec;
sub handler(Apache::RequestRec $r)
{
my ($status, $pw) = $r.get_basic_auth_pw();
return ($pw eq 'squawk') ? OK : HTTP_UNAUTHORIZED;
}
Компилится он в байт-код с таким же успехом , как и аналогичный pir-код.
Выбор же , на чем писать , нужно будет сделать уже вам :-)
Сейчас идет окончательная фаза доделывания пэррот ,
притирка к апи , а также реализация виндовой поддержки .
Нет поддержки для CGI-скриптов .
В общем , ждем-с 6-й перл.
|