On Friday, October 22, 2010 17:19:15 Alexander Farber wrote:
> Hello,
> 
> I have a simple protocol handler which writes a string to client
> socket (source code below).
> 
> I would like to make that string configurable through httpd.conf, so
> that I could say there:
> 
>   Listen 843
>   <VirtualHost _default_:843>
>        MyPolicyString            "<xml>blah</xml>"
>        PerlModule                   SocketPolicy
>        PerlProcessConnectionHandler SocketPolicy
>   </VirtualHost>
> 
> I keep reading http://perl.apache.org/docs/2.0/user/ and other docs,
> but just can't find how to do it. Do you use PerlPostConfigHandler for
> that and how would I get that string in my
> PerlProcessConnectionHandler?
> 
> I've noticed, that I could use a Apache2::Directive or a
> $r->dir_config("MyPerlVar") but those seem to be slower and are
> mod_perl-ish. I would like to use the mod_perl method corresponding to
> the command_rec structure in C, where you would use an AP_INIT_TAKE1
> (I guess... I'm not an expert here).

use Apache2::CmdParms ();
use Apache2::Directive ();
use Apache2::Module ();

my @directives=
  (
   {
    name         => 'SocketPolicyString',
    req_override => Apache2::Const::RSRC_CONF,
    args_how     => Apache2::Const::TAKE1,
    errmsg       => '...',
   },
   ...
  );
Apache2::Module::add(__PACKAGE__, \...@directives);

sub SocketPolicyString {
  my(undef, $parms, $arg)=...@_;
  my $cf=Apache2::Module::get_config(__PACKAGE__, $parms->server);

  $cf->{policystring}=$arg;
}

# merge merges the configurations of the vhost and the base server to build
# the final config for the vhost. that means here a vhost inherits from the
# base server.
sub SERVER_MERGE {
  my ($base, $add)=...@_;
  my %merged;

  if( exists $add->{policystring} ) {
    $merged{policystring}=$add->{policystring};
  } else {
    $merged{policystring}=$base->{policystring};
  }

  return bless \%merged, ref($base);
}

# This is called only if there is at least one directive for the module in the
# httpd.conf for the server
sub SERVER_CREATE {
  my ($class, $parms)=...@_;

  return bless {
                policystring=>'defaultpolicy',
               } => $class;
}


Put something like that outside any function in your module.

In the httpd.conf you need to use PerlLoadModule instead of PerlModule to load 
the module. After that you should be able to use

SocketPolicyString "hugo"

That is a short outline compiled from my memory. I may have missed something 
here very well.

Then at runtime (in your handler):

$cf=Apache2::Module::get_config( __PACKAGE__, $conn->base_server );

There is more documentation on this on the site. Search for SERVER_MERGE or 
so.

It is also possible to create container directives which is more convenient 
for the user if the policy string may become longer. The user can then put it 
as

<SocketPolicyString some parameters>
  blah blah
</SocketPolicyString>

The corresponding @directives element would look like:
   {
    name         => '<SocketPolicyString',
    func         => __PACKAGE__.'::SocketPolicyContainer',
    req_override => Apache2::Const::RSRC_CONF,
    args_how     => Apache2::Const::RAW_ARGS,
    errmsg       => <<'EOF',
<SocketPolicyString ...>
    ...
</SocketPolicyString>
EOF
   },

and you'd have to implement a SocketPolicyContainer function and the 
corresponding stuff in SERVER_CREATE/_MERGE as well.

sub SocketPolicyContainer {
  my(undef, $parms, $rest)=...@_;
  $cf=Apache2::Module::get_config(__PACKAGE__, $parms->server);

  # $rest contains the stuff after "<SocketPolicyString" up to the closing ">"
  # the stuff between the opening and closing "<SocketPolicyString>" lines is
  # read as $parms->directive->as_string
  ...
}

You can have both the simple string SocketPolicyString directive and the 
container directive at once.

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

Reply via email to