Re: How to access client socket from a protocol handler

2010-10-23 Thread Alexander Farber
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

2010-10-23 Thread rm
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

2010-10-23 Thread Ben Noordhuis
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

2010-10-23 Thread Alexander Farber
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

2010-10-23 Thread Ben Noordhuis
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

2010-10-23 Thread Alexander Farber
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

2010-10-23 Thread Ben Noordhuis
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.