Можно ли написать обработчик протокола Apache на PHP? - PullRequest
2 голосов
/ 22 октября 2010

Интересно, можно ли и как написать собственный «обработчик протокола» (прослушивание через пользовательский порт) для Apache 2 в PHP?

В C и mod_perl вы можете написать так называемые «обработчики протокола», которые перехватывают раннюю стадию Apache (после того, как соединение с сокетом клиента было принято (), но до того, как в него был записан какой-либо контент), и могут для пример дескриптора FTP или SMTP протоколов. Возможно ли это и в PHP?

Например, у меня есть следующий простой обработчик mod_perl, который я хотел бы перенести на PHP (для сравнения использования памяти - так как моему обработчику mod_perl требуется 20 м на каждого ребенка). Мой обработчик прослушивает порт 843 и записывает строку POLICY в сокет клиента:

package SocketPolicy;

# Run: semanage port -a -t http_port_t -p tcp 843
# And add following lines to the httpd.conf
# Listen 843
# <VirtualHost _default_:843>
#       PerlModule                   SocketPolicy
#       PerlProcessConnectionHandler SocketPolicy
# </VirtualHost>

use strict;
use warnings FATAL => 'all';
use APR::Const(-compile => 'SO_NONBLOCK');
use APR::Socket();
use Apache2::ServerRec();
use Apache2::Connection();
use Apache2::Const(-compile => qw(OK DECLINED));

use constant POLICY =>
qq{<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="8080"/>
</cross-domain-policy>
\0};

sub handler {
        my $conn   = shift;
        my $socket = $conn->client_socket();
        my $offset = 0;

        # set the socket to the blocking mode
        $socket->opt_set(APR::Const::SO_NONBLOCK => 0);

        do {
                my $nbytes = $socket->send(substr(POLICY, $offset),
                             length(POLICY) - $offset);
                # client connection closed or interrupted
                return Apache2::Const::DECLINED unless $nbytes;
                $offset += $nbytes;
        } while ($offset < length(POLICY));

        my $slog = $conn->base_server()->log();
        $slog->warn('served socket policy to: ', $conn->remote_ip());
        return Apache2::Const::OK;
}

1;

Спасибо, Alex

Ответы [ 4 ]

1 голос
/ 22 октября 2010

Нет, mod_php не реализует фазы обработчика Apache, которые делает mod_perl.

См. http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/sapi/apache2handler/php_functions.c?revision=296107&view=markup#l516

0 голосов
/ 22 октября 2010

Да и нет .... PHP имеет интерфейс Apache, который использует API-обработчик Apache, а также другие интерфейсы, такие как CLI, CGI и т. Д. Интеграция PHP Apache API решает не раскрывать детали обработки более низкого уровнякак и mod_perl, поэтому, если вам нужен доступ к этим обратным вызовам, вам придется написать свою собственную реализацию API обработчика PHP Apache.

0 голосов
/ 22 октября 2010

Это вполне возможно .... даже полный веб-сервер написан на PHP

0 голосов
/ 22 октября 2010

Технически да, вы можете с расширением сокета , учитывая, что вы также позволяете скрипту работать достаточно долго.По умолчанию сценарий PHP будет прерван через 60 секунд или около того.

Таким образом, основная проблема заключается в том, чтобы скрипт PHP работал как демон.

...