App-HTTP_Proxy_IMP

 view release on metacpan or  search on metacpan

examples/DelayRequest.pm  view on Meta::CPAN


use strict;
use warnings;
package DelayRequest;
use base 'Net::IMP::HTTP::Request';
use fields qw(delayed);

use Net::IMP;
use Net::IMP::HTTP;
use Net::IMP::Debug;
use Scalar::Util 'weaken';

sub RTYPES { ( IMP_PASS ) }

sub new_analyzer {
    my ($class,%args) = @_;
    my $self = $class->SUPER::new_analyzer(%args);
    $self->run_callback(
	# we don't need to look at response
	[ IMP_PASS,1,IMP_MAXOFFSET ],
    );

examples/DelayRequest.pm  view on Meta::CPAN

	    if (
		$data =~m{^Referer:\s*\Q$base}mi       # same origin
		|| $data =~m{^Referer:\s*https?://}mi  # at least from another site
	    ) {
		# no delay
		$self->run_callback([ IMP_PASS,0,IMP_MAXOFFSET ]);
		return;
	    }
	}

	weaken(my $wself = $self);
	$self->{delayed} = $self->{factory_args}{eventlib}->timer(
	    $self->{factory_args}{delay} || 0.5,
	    sub {
		# pass thru everything 
		$wself or return;
		$wself->{delayed} = undef;
		$wself->run_callback([ IMP_PASS,0,IMP_MAXOFFSET ]);
	    }
	);
    }

lib/App/HTTP_Proxy_IMP/Conn.pm  view on Meta::CPAN

# derived from Net::Inspect::L7::HTTP
# just pipes all input into conn->in(...)
############################################################################

use strict;
use warnings;

package App::HTTP_Proxy_IMP::Conn;
use base 'Net::Inspect::L7::HTTP';
use App::HTTP_Proxy_IMP::Debug;
use Scalar::Util 'weaken';
use fields (
    # all connections
    'pcapdir',     # dir for writing pcaps
    'mitm',        # IO::Socket::SSL::Intercept object for SSL interception
    'capath',      # path to file|direcory with CA certificates
    'imp_factory', # App::HTTP_Proxy_IMP::IMP factory
    # per connection
    'spool',       # any data which cannot be processed yet?
    'pcapw',       # Net::PcapWriter object
    'intunnel',    # true if connections is inside intercepted SSL tunnel

lib/App/HTTP_Proxy_IMP/Conn.pm  view on Meta::CPAN

	    or die "cannot open pcap file: $!";
	$fh->autoflush;
	my $w = Net::PcapWriter->new($fh);
	my $c = $w->tcp_conn( 
	    $meta->{daddr}, $meta->{dport},
	    $meta->{saddr}, $meta->{sport} 
	);
	$obj->{pcapw} = [$c,$w],
    }

    weaken( $obj->{relay} = $relay );
    return $obj;
}

sub in {
    my $self = shift;
    return $self->SUPER::in(@_) if ! $self->{pcapw};
    my ($dir,$data,$eof,$time) = @_;
    if ( defined ( my $bytes = eval { $self->SUPER::in(@_) } )) {
	$self->{pcapw}[0]->write($dir,substr($data,0,$bytes));
	return $bytes;

lib/App/HTTP_Proxy_IMP/IMP.pm  view on Meta::CPAN

use strict;
use warnings;

package App::HTTP_Proxy_IMP::IMP;

use Net::Inspect::Debug qw(:DEFAULT $DEBUG);
use Net::IMP::Debug var => \$DEBUG, sub => \&debug;
use Net::IMP qw(:DEFAULT :log);
use Net::IMP::HTTP;
use Scalar::Util 'weaken';
use Hash::Util 'lock_ref_keys';
use Compress::Raw::Zlib;
no warnings 'experimental'; # smartmatch
use Carp;

my %METHODS_RFC2616 = map { ($_,1) } qw( GET HEAD POST PUT DELETE OPTIONS CONNECT TRACE );
my %METHODS_WITHOUT_RQBODY = map { ($_,1) } qw( GET HEAD DELETE CONNECT );
my %METHODS_WITH_RQBODY = map { ($_,1) } qw( POST PUT );
my %CODE_WITHOUT_RPBODY = map { ($_,1) } qw(204 205 304);
my %METHODS_WITHOUT_RPBODY = map { ($_,1) } qw(HEAD);

lib/App/HTTP_Proxy_IMP/IMP.pm  view on Meta::CPAN

	pass => [0,0],      # pass allowed up to given offset (per dir)
	prepass => [0,0],   # prepass allowed up to given offset (per dir)
	fixup_header => [], # sub to fixup content-length in header once known
	eof => [0,0],       # got eof in dir ?
	decode => undef,    # decoder for content-encoding decode{type}[dir]
	pass_encoded => undef, # pass body encoded (analyzer will not change body)
	method => undef,    # request method
	logsub => $factory->{logsub},  # how to log IMP_OG
    }, ref($factory);
    lock_ref_keys($self);
    weaken($self->{request});

    # set callback, this might trigger callback immediately if there are 
    # results pending
    weaken( my $wself = $self );
    $analyzer->set_callback( sub { _imp_callback($wself,@_) } );
    return $self;
}


sub request_header {
    my ($self,$hdr,$xhdr,@callback) = @_;
    my $clen = $xhdr->{content_length};

    # new body might change content-length info in request header

lib/App/HTTP_Proxy_IMP/Relay.pm  view on Meta::CPAN

use warnings;

package App::HTTP_Proxy_IMP::Relay;
use fields (
    'fds',      # file descriptors
    'conn',     # App::HTTP_Proxy_IMP::HTTPConn object
    'acct',     # collect accounting
);

use App::HTTP_Proxy_IMP::Debug;
use Scalar::Util 'weaken';
use IO::Socket::SSL;
use AnyEvent;
use POSIX '_exit';

# set if the child should destroy itself after last connection closed
my $exit_if_no_relays;
sub exit_if_no_relays { $exit_if_no_relays = pop; }

# active relay, inserted in new, removed in $idlet timer
my @relays;

lib/App/HTTP_Proxy_IMP/Relay.pm  view on Meta::CPAN

	sport => $cfd->peerport,
	upstream => $upstream,
    },$self);

    #debug("create connection $cobj");
    $self->{conn} = $cobj;
    my $cfo = $self->{fds}[0] = App::HTTP_Proxy_IMP::Relay::FD->new(0,$cfd,$self,1);
    $cfo->mask( r => 1 ); # enable read 

    push @relays, $self;
    weaken($relays[-1]);

    return $self;
}

sub DESTROY {
    my $self = shift;
    $self->account('destroy');
    $self->xdebug("destroy relay $self");
    if ( $exit_if_no_relays && ! $self->relays ) {
	# der letzte macht das Licht aus

lib/App/HTTP_Proxy_IMP/Relay.pm  view on Meta::CPAN

    # destroy the current connection object and create a new obne
    $conn = $self->{conn} = $conn->clone;
    $conn->{intunnel} = 1;
    
    my $sfo = $self->{fds}[$from] or return
	$self->fatal("cannot startssl $from - no such fo");

    # stop handling all data
    $self->mask($to,r=>0);
    $self->mask($from,r=>0);
    weaken( my $wself = $self );

    my %sslargs = (
	SSL_verifycn_name => $hostname,
	SSL_verifycn_schema => 'http',
	SSL_hostname => $hostname, # SNI
	$conn->{capath} ? (
	    SSL_verify_mode => SSL_VERIFY_PEER,
	    ( -d $conn->{capath} ? 'SSL_ca_path' : 'SSL_ca_file' ), 
	    $conn->{capath}
	):( 

lib/App/HTTP_Proxy_IMP/Relay.pm  view on Meta::CPAN

        }
    }
);

############################################################################
# Filehandle
############################################################################

package App::HTTP_Proxy_IMP::Relay::FD;
use Carp 'croak';
use Scalar::Util 'weaken';
use App::HTTP_Proxy_IMP::Debug;
use AnyEvent::Socket qw(tcp_connect format_address);
use IO::Socket::SSL;

use fields (
    'dir',        # direction 0,1
    'fd',         # file descriptor
    'host',       # destination hostname
    'status',     # bitmap of read_shutdown|write_shutdown|connected
    'relay',      # weak link to relay

lib/App/HTTP_Proxy_IMP/Relay.pm  view on Meta::CPAN

    'wwatch',     # AnyEvent watcher - undef if write is disabled
    'wsrc',       # source of writes for stalled handling
);

sub new {
    my ($class,$dir,$fd,$relay,$connected) = @_;
    my $self = fields::new($class);
    $self->{dir} = $dir;
    $self->{fd} = $fd;
    $self->{status} = $connected ? 0b001 : 0;
    #weaken( $self->{relay} = $relay );
    $self->{relay} = $relay;
    $self->{rbuf} = $self->{wbuf} = '';
    return $self;
}

sub xdebug {
    my $self = shift;
    my $conn = $self->{relay}{conn};
    if ( my $xdebug = UNIVERSAL::can($conn,'xdebug') ) {
	my $msg = "[$self->{dir}] ".shift(@_);

lib/App/HTTP_Proxy_IMP/Request.pm  view on Meta::CPAN

    'defer_rqbody', # deferred request body (wait until header can be sent)

    'method',       # request method
    'rqhost',       # hostname from request
    'rq_version',   # version of request
    'rp_encoder',   # sub to encode response body (chunked)
    'keep_alive',   # do we use keep_alive in response
);

use App::HTTP_Proxy_IMP::Debug qw(debug $DEBUG debug_context);
use Scalar::Util 'weaken';
use Net::Inspect::Debug 'trace';
use Net::IMP qw(:DEFAULT :log);
use Net::IMP::HTTP; # constants
use Sys::Hostname 'hostname';

my $HOSTNAME = hostname();

# connected to host or do we fake the response internally
use constant CONN_HOST => 1;
use constant CONN_INTERNAL => 2;

lib/App/HTTP_Proxy_IMP/Request.pm  view on Meta::CPAN

sub DESTROY { 
    $DEBUG && debug("destroy request"); 
    #Devel::TrackObjects->show_tracked;
}
sub new_request {
    my ($factory,$meta,$conn) = @_;
    my $self = $factory->new;
    $DEBUG && $conn->xdebug("new request $self");

    $self->{meta} = $meta;
    weaken($self->{conn} = $conn);
    $self->{defer_rqhdr} = $self->{defer_rqbody} = '';

    $self->{acct} = { %$meta, Id => $self->id };
    if ( my $f = $conn->{imp_factory} ) {
	$self->{imp_analyzer} = $f->new_analyzer($self,$meta);
    }

    $self->{me_proxy} = $HOSTNAME;
    $self->{up_proxy} = $meta->{upstream};



( run in 0.389 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )