httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexander Farber <alexander.far...@gmail.com>
Subject Re: How to access client socket from a protocol handler
Date Sat, 23 Oct 2010 06:21:25 GMT
Hello Ben and others

On Sat, Oct 23, 2010 at 12:52 AM, Ben Noordhuis <info@bnoordhuis.nl> wrote:
> On Sat, Oct 23, 2010 at 00:15, Alexander Farber
> the conn_config solution is most portable across Apache versions.
>
>> And what do you mean by &core_module
>> in my case (source code below)?
>
> That's the reference to Apache itself, the core is a module too.
> Elegant, isn't it?

yes, I've decided to try the easy way first and have added

    #define CORE_PRIVATE
    #include <http_core.h>

and

    apr_socket_t *socket = ap_get_module_config(conn->conn_config,
&core_module);
    apr_size_t len = strlen(POLICY);
    apr_socket_send(socket, POLICY, &len);

to my module (full source at the bottom of the mail).
And I have appended the following to httpd.conf:

    LoadModule socket_policy_module modules/mod_socket_policy.so
    Listen 843
    <VirtualHost _default_:843>
        SetHandler socket_policy
    </VirtualHost>

And can see

tcp        0      0 :::843                      :::*
     LISTEN

and can get my string by "telnet localhost 843" and pressing ENTER.

But this has broken my web server - it serves that string
now over port 80 as well - for any request I do.

Is the easy solution _that_ evil? :-)

And how does mod_perl 2 succeeds the same task,
because my mod_perl module works ok?

> You should strive to use what is already in place, if only because it
> will make your life easier down the road. Upsides to using the bucket
> brigade and the filter chain:
>
> * cross-platform
> * published and supported APIs (will work with future releases of Apache)
> * fairly straight-forward and transparent SSL/TLS integration
>
> Downsides:
>
> * overhead (slower)
> * higher learning curve

I have read about BB, but haven't understood them yet
and I don't understand how to use them in my case.

Regards
Alex

=== Here is my broken mod_socket_policy.c: ===

#include <httpd.h>
#include <http_protocol.h>
#include <http_connection.h>
#include <http_config.h>
#include <http_log.h>
#define CORE_PRIVATE
#include <http_core.h>

#define POLICY "<?xml version=\"1.0\"?>\n" \
               "<!DOCTYPE cross-domain-policy SYSTEM\n" \
               "\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" \
               "<cross-domain-policy>\n" \
               "<allow-access-from domain=\"*\" to-ports=\"8080\"/>\n" \
               "</cross-domain-policy>\0"

static int socket_policy_handler(conn_rec *conn) {
        apr_socket_t *socket = ap_get_module_config(conn->conn_config,
&core_module);
        apr_size_t len = strlen(POLICY);

        apr_socket_send(socket, POLICY, &len);

        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, conn->base_server,
                "served socket policy to %s", conn->remote_ip);

        return OK;
}

static void register_hooks(apr_pool_t *pool) {
        ap_hook_process_connection(socket_policy_handler, NULL, NULL,
APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA socket_policy_module = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        register_hooks
};

=== Here is mod_perl module, it works, but needs mucho memory ===

package SocketPolicy;

# 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;

Mime
View raw message