是否可以用 PHP 编写 Apache 协议处理程序?

发布于 2024-09-28 18:25:20 字数 2004 浏览 6 评论 0原文

我想知道是否以及如何可以在 PHP 中为 Apache 2 编写自定义“协议处理程序”(在自定义端口监听)?

在 C 和 mod_perl 中,您可以编写所谓的“协议处理程序”,它拦截早期的 Apache 阶段(在客户端套接字连接被接受()之后,但在写入任何内容之前)并且可以例如处理 < a href="http://httpd.apache.org/mod_ftp/" rel="nofollow">FTP 或 SMTP 协议。 PHP 中也可以吗?

例如,我有以下简单的 mod_perl 处理程序,我想将其移植到 PHP(以比较内存使用情况 - 因为我的 mod_perl 处理程序每​​个子进程需要 20m)。我的处理程序侦听端口 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;

谢谢, 亚历克斯

I wonder if and how it is possible to write a custom "protocol handler" (listening at a custom port) for Apache 2 in PHP?

In C and mod_perl you can write so-called "protocol handlers", which intercept the early Apache stage (after a client socket connection has been accept()ed, but before any content has been written to it) and can for example handle FTP or SMTP protocols. Is it possible in PHP as well?

For example, I have the following simple mod_perl handler, which I'd like to port to PHP (to compare the memory usage - since my mod_perl-handler needs 20m per child). My handler listens at the port 843 and writes the string POLICY to the client socket:

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;

Thanks,
Alex

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

著墨染雨君画夕 2024-10-05 18:25:20

从技术上讲,是的,您可以使用套接字扩展,因为您还允许脚本运行足够长了。默认情况下,PHP 脚本将在 60 秒左右后终止。

所以主要问题是让 PHP 脚本像守护进程一样运行。

Technically yes you can with the socket extension given that you also allow you script to run long enough. By default a PHP script will be terminated after 60 sec or so.

So the main issue is to keep your PHP script running like a daemon.

吃兔兔 2024-10-05 18:25:20

这是完全有可能的......甚至还有一个用 PHP 编写的 完整的 Web 服务器

It's perfectly possible.... there's even a full web server written in PHP

丢了幸福的猪 2024-10-05 18:25:20

是和否...PHP 有一个 Apache 接口,它使用 Apache 处理程序 API,以及其他接口,例如 CLI、CGI 等。PHP Apache API 集成选择不公开较低级别的处理细节,如 mod_perl 那样,因此如果您需要访问这些回调,您必须编写自己的 PHP Apache 处理程序 API 实现。

Yes and no.... PHP has an Apache interface which uses the Apache handler API, as well as other interfaces, such as CLI, CGI etc. The PHP Apache API integration chooses not to expose the lower-level handling details like mod_perl does, so if you need access to these callbacks you'll have to write your own PHP Apache handler API implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文