App-HTTP_Proxy_IMP
view release on metacpan or search on metacpan
lib/App/HTTP_Proxy_IMP.pm view on Meta::CPAN
);
}
my $imp_factory;
my $filter = $self->{filter};
if ($filter && @$filter ) {
my $ns = $self->{impns};
my @mod;
my $ev = App::HTTP_Proxy_IMP::EventLoop->new;
for my $f (@$filter) {
if ( ref($f) ) {
# already factory object
push @mod,$f;
next;
}
my $f = $f; # copy
my $args = $f =~s{=(.*)}{} && $1;
my $found;
for my $prefix ('', map { "${_}::" } @$ns) {
my $mod = $prefix.$f;
if ( eval "require $mod" ) {
$found = $mod;
last;
}
}
croak("IMP module $f could not be loaded: $@") if ! $found;
my %args = $args ? $found->str2cfg($args) :();
my @err = $found->validate_cfg(%args);
die "bad config for $found: @err" if @err;
push @mod, $found->new_factory(%args, eventlib => $ev )
}
my $logsub = $self->{logrx} && do {
my $rx = $self->{logrx};
sub {
my ($level,$msg,$dir,$off,$len) = @_;
$level =~ $rx or return;
print STDERR "[$level]($dir:$off,$len) $msg\n";
};
};
$imp_factory = App::HTTP_Proxy_IMP::IMP->new_factory(
mod => \@mod,
logsub => $logsub,
);
}
if ( $self->{childs} ) {
$self->{childs} = [ map { undef } (1..$self->{childs}) ];
}
my $capath;
if ( ! $mitm ) {
# no interception = no certificate checking
} elsif ( $self->{no_check_certificate} ) {
# no certificate checking
} elsif ( $capath = $self->{capath} ) {
# use this capath
} else {
# try to guess capath
if ( eval { require Mozilla::CA } ) {
$capath = Mozilla::CA::SSL_ca_file();
} elsif ( glob("/etc/ssl/certs/*.pem") ) {
$capath = "/etc/ssl/certs";
} elsif ( -f "/etc/ssl/certs.pem" && -r _ && -s _ ) {
$capath = "/etc/ssl/certs.pem";
} else {
croak "cannot determine CA path, needed for SSL interception"
}
}
# create connection fabric, attach request handling
my $req = App::HTTP_Proxy_IMP::Request->new;
my $conn = App::HTTP_Proxy_IMP::Conn->new($req,
pcapdir => $pcapdir,
mitm => $mitm,
capath => $capath,
imp_factory => $imp_factory
);
# create listeners
my @listen;
$self->{addr} = [ $self->{addr} ]
if $self->{addr} && ref($self->{addr}) ne 'ARRAY';
for my $spec (@{$self->{addr}}) {
my ($addr,$upstream) =
ref($spec) eq 'ARRAY' ? @$spec:
ref($spec) ? ( $spec,undef ):
split('=',$spec,2);
my $srv;
if ( ref($addr)) {
# listing socket already
$srv = $addr;
(my $port,$addr) = AnyEvent::Socket::unpack_sockaddr( getsockname($srv));
$addr = AnyEvent::Socket::format_address($addr);
$addr = $addr =~m{:} ? "[$addr]:$port" : "$addr:$port";
} else {
$srv = $sockclass->new(
LocalAddr => $addr,
Listen => 10,
ReuseAddr => 1,
) or croak("cannot listen to $addr: $!");
}
$spec = [ $addr,$upstream,$srv ];
push @listen, AnyEvent->io(
fh => $srv,
poll => 'r',
cb => sub {
my $cl = $srv->accept or return;
debug("new request from %s:%s on %s",$cl->peerhost,$cl->peerport,$addr);
if ( $self->{max_connect_per_child}>0
and 0 == --$self->{max_connect_per_child} ) {
# last connection for child
# fork-away and handle outstanding connections, parent will
# in the meantime fork a replacement child
defined( my $pid = fork()) or die "failed to fork: $!";
if ( $pid ) {
$DEBUG && debug("forked away child $$ as $pid");
_exit(0);
( run in 1.355 second using v1.01-cache-2.11-cpan-39bf76dae61 )