http://perl.apache.org/docs/2.0/user/porting/compat.html – A Reference to mod_perl 1.0 to mod_perl 2.0 Migration, подробный список “что на что менять”
http://perl.apache.org/docs/2.0/user/porting/porting.html – Общее обсуждение mod_perl 1.0 и mod_perl 2.0
http://perl.apache.org/docs/1.0/guide/config.html – mod_perl Configuration (1.0)
http://perl.apache.org/docs/2.0/user/index.html – документация по mod_perl2
http://perl.apache.org/docs/2.0/user/config/config.html – mod_perl 2.0 Server Configuration
http://perl.apache.org/docs/2.0/user/handlers/intro.html – все про mod_perl’овые хендлеры (2.0)
http://perl.apache.org/docs/2.0/user/coding/coding.html – Writing mod_perl Handlers and Scripts
PerlRequire directive not allowed in a <Location>
block
$r->notes
… in mod_perl 2.0, $r->notes() returns an APR::Table object, which can be used as a tied hash or calling its get() / set() / add() / unset() methods.
http://perl.apache.org/docs/2.0/user/porting/compat.html
UseCanonicalName Off, иначе все плохо
Под 1.3 работало и с UseCanonicalName On
http://web.archiveorange.com/archive/v/wudV5MzM5e5mzvzkmFOY – пишут интересное:
“It seems that get_server_port gives the wrong answer when responding to an HTTP/1.0 request. That is, it always says port ‘80’ for HTTP/1.0”
“the behavior of ap_get_server_port looks to be very different between apache 1.3 and 2.0, so I suspect the difference is really there.”
Наблюдаемое поведение: внутри PerlResponseHandler ModPerl::Registry – ok, переменная $ENV{REMOTE_ADDR}
есть.
А в модуле, установленном как PerlFixupHandler для того же локейшена – не ok, переменная пуста.
Решение:
$r->connection->remote_ip
– там правильное значение$r->subprocess_env;
– тогда появлятся %ENV
, в т.ч. и $ENV{REMOTE_ADDR}
Цитата из документации по $r->subprocess_env
(http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html):
When called in VOID context with no arguments, it populate
%ENV
with special variables (e.g.$ENV{QUERY_STRING}
) like mod_cgi does.
http://perl.apache.org/docs/2.0/user/porting/compat.html
Apache::Registry, Apache::PerlRun and other modules from the registry family now live in the ModPerl:: namespace. In mod_perl 2.0 we put mod_perl specific functionality into the ModPerl:: namespace, similar to APR:: and Apache2:: which are used for libapr and Apache, respectively.
ModPerl::Registry (and others) doesn’t chdir() into the script’s dir like Apache::Registry does, because chdir() affects the whole process under threads. If you need this functionality use ModPerl::RegistryPrefork or ModPerl::PerlRunPrefork.
PerlHandler was replaced with PerlResponseHandler.
http://perl.apache.org/docs/2.0/user/porting/compat.html
mod_perl 1.0 back-compatibility directives:
Жизненный цикл (фазы) запроса: http://perl.apache.org/docs/2.0/user/handlers/http.html#HTTP_Request_Cycle_Phases
Нескольно хендлеров на одну фазу == “stacked handlers”.
http://perl.apache.org/docs/2.0/user/porting/compat.html#Stacked_Handlers
Both mod_perl 1.0 and 2.0 support the ability to register more than one handler in each runtime phase, a feature known as stacked handlers.
The behavior of stacked Perl handlers differs between mod_perl 1.0 and 2.0. In 2.0, mod_perl respects the run-type of the underlying hook - it does not run all configured Perl handlers for each phase but instead behaves in the same way as Apache does when multiple handlers are configured, respecting (or ignoring) the return value of each handler as it is called.
http://perl.apache.org/docs/2.0/user/handlers/intro.html#Stacked_Handlers
For each phase there can be more than one handler assigned (also known as hooks, because the C functions are called ap_hook_<phase_name>
). Phases’ behavior varies when there is more then one handler registered to run for the same phase.
VOID
Handlers of the type VOID will be all executed in the order they have been registered disregarding their return values. Though in mod_perl they are expected to return Apache2::Const::OK.
RUN_FIRST
Handlers of the type RUN_FIRST will be executed in the order they have been registered until the first handler that returns something other than Apache2::Const::DECLINED. If the return value is Apache2::Const::DECLINED, the next handler in the chain will be run. If the return value is Apache2::Const::OK the next phase will start. In all other cases the execution will be aborted.
RUN_ALL
Handlers of the type RUN_ALL will be executed in the order they have been registered until the first handler that returns something other than Apache2::Const::OK or Apache2::Const::DECLINED.
PerlResponseHandler – RUN_FIRST
Из документации на APR::Table (http://search.cpan.org/~phred/mod_perl/docs/api/APR/Table.pod):
APR::Table allows its users to manipulate opaque string-content tables.
On the C level the “opaque string-content” means: you can put in ‘\0’-terminated strings and whatever you put in your get out.
On the Perl level that means that we convert scalars into strings and store those strings. Any special information that was in the Perl scalar is not stored. So for example if a scalar was marked as utf8, tainted or tied, that information is not stored. When you get the data back as a Perl scalar you get only the string.
Что делать, варианты:
1.
Явно декодировать строки (и самостоятельно отслеживать, что надо декодировать, а что нет)
2.
Пользоваться pnotes
Важно: для записи в access.log Apache может пользоваться значениями из notes (пример: %{uid}n
, вообще %...{Foobar}n
– The contents of note Foobar from another module.).
Их надо по-прежнему записывать в notes, не только в pnotes.
3.
Наследоваться и делать utf-обертки
Устанавливаем куку и делаем редирект.
Документация по Apache и Apache2::RequestRec говорит, что для этого подходит $r->err_headers_out
, цитата:
The difference between headers_out and err_headers_out, is that the latter are printed even on error
Однако под Apache 1.3 работала и конструкция headers_out + редирект (кука устанавливалась). А под Apache 2.2 – нет, при редиректе надо использовать err_headers_out
Умолчательное поведение отличается для разных фаз обработки запроса
См. http://perl.apache.org/docs/2.0/user/config/config.html, опция GlobalRequest:
Setup the global $r
object for use with Apache2->request
.
This setting is enabled by default during the PerlResponseHandler phase for sections configured as:
but is not enabled by default for sections configured as:
And can be disabled with:
Notice that if you need the global request object during other phases, you will need to explicitly enable it in the configuration file.
You can also set that global object from the handler code, like so: