Re: How to access client socket from a protocol handler
Hello Ben and others On Sat, Oct 23, 2010 at 12:52 AM, Ben Noordhuis i...@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 tcp0 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;
Re: Strange EOS bucket in filter
On Sat, Oct 23, 2010 at 12:55:05PM +0200, r...@tuxteam.de wrote: On Sat, Oct 23, 2010 at 11:22:20AM +0100, Nick Kew wrote: On 23 Oct 2010, at 11:06, r...@tuxteam.de wrote: Hello list, I'm currently developing an output filter that , dpending on some condition either parses all data to convert it (and hence don't pass any of the incomming buckets down the pipe) or decides to leave the data as it is and just pushes all incomming buckets down. Now, strangely, for the second case every second request my filter only gets an EOS bucket (as the first bucket te filter sees) for all resources that the filter doesn't need to touch. This only seems to happen for requests with keep-alive true. That somehow sounds like someting I've encoutered before but I can't recall when or where :-/ Any ideas what's going on? Are you clearing all the input once you've consumed it? You mean input buckets that i get as a the brigade parameter in my filter callback? Yes, at least mod_diagnostics shows an EOS buffer comming from my filter as the last buffer for that request. Strange Ah, found some hint: this only happens when I run the request through a proxy (had accidently set http_proxy in my debugging shell ...). Hm: I can narrow this dow to a second request with an If-Modified-Since header with the same value as the last sent Last-Modified header. So 304/Not-Modified will still chase an EOF through the content filter chain? Good to know ... Thanks RalfD -- Nick Kew
Re: How to access client socket from a protocol handler
On Sat, Oct 23, 2010 at 10:13, Alexander Farber alexander.far...@gmail.com wrote: I wonder why my mod_perl module works and the C one not. Your connection handler should return DECLINED for vhosts it doesn't handle (I wager mod_perl did this for you). You can get the vhost with conn-base_server and your module's per-server config with ap_get_module_config(conn-base_server-module_config, your_module).
Re: How to access client socket from a protocol handler
Hello Ben, On Sat, Oct 23, 2010 at 2:08 PM, Ben Noordhuis i...@bnoordhuis.nl wrote: On Sat, Oct 23, 2010 at 10:13, Alexander Farber alexander.far...@gmail.com wrote: Your connection handler should return DECLINED for vhosts it doesn't handle (I wager mod_perl did this for you). You can get the vhost with conn-base_server and your module's per-server config with ap_get_module_config(conn-base_server-module_config, your_module). sorry, but I don't understand - 1) your original suggestion was to use apr_socket_t *socket = ap_get_module_config(conn-conn_config, core_module); but I don't understand why it returns a socket instead of a config struct? 2) And now you suggest to ap_get_module_config(conn-base_server-module_config, your_module); Yes, I know that it will return a custom config struct for my module, which I can prepare/merge in the earlier handlers, but how does it help me to access the client socket for my VirtualHost at port 843 3) And finally you tell me to return DECLINED for vhosts my module doesn't handle, but how can I recognize them in my protocol handler? Regards Alex
Re: How to access client socket from a protocol handler
Alexander, take a look at mod_echo.c (included in the source tarball). It's a great example of how a protocol handler should work and it just might convince you to use bucket brigades after all. :) You need to check if your handler is enabled for the current vhost. If it's not, return DECLINED. If it is, look up the client socket and go from there.
Re: How to access client socket from a protocol handler
No, SetHandler should be ok, because mod_echo works fine. I've added the port number to my logs: ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, conn-base_server, served socket policy to %s via %d, conn-remote_ip, conn-base_server-port); And now I see in the error_log: [notice] served socket policy to 127.0.0.1 via 843 [notice] served socket policy to 127.0.0.1 via 80 - depending on which port I called the telnet localhost XXX with. So should I check for the port != 843 and return DECLINED? It seems a bit awkward to me Regards Alex
Re: How to access client socket from a protocol handler
On Sun, Oct 24, 2010 at 00:00, Alexander Farber alexander.far...@gmail.com wrote: I've created a module using bb (the source code at the bottom) and it suffers from the same problem (hijacks the port 80 too). Could it be that SetHandler is a wrong directive for protocol handler? The wrong directive, yes. SetHandler handlers work at the request level, protocol handlers at the connection level. Also, I do not know, how to check that the handler is enabled for the current vhost. From mod_echo.c: static int process_echo_connection(conn_rec *c) { EchoConfig *pConfig = ap_get_module_config(c-base_server-module_config, echo_module); if (!pConfig-bEnabled) { return DECLINED; } Hope that helps.