App-HTTP_Proxy_IMP

 view release on metacpan or  search on metacpan

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


use strict;
use warnings;
package App::HTTP_Proxy_IMP::IMP::FakeResponse;
use base 'Net::IMP::HTTP::Request';
use fields qw(root file response);
no warnings 'experimental'; # smartmatch

use Net::IMP;
use Net::IMP::Debug;
use Carp;
use Digest::MD5;

sub RTYPES { ( IMP_PASS,IMP_REPLACE,IMP_DENY,IMP_ACCTFIELD ) }

sub new_factory {
    my ($class,%args) = @_;
    my $dir = $args{root} or croak("no root directory given");
    -d $dir && -r _ && -x _ or croak("cannot use base dir $dir: $!");
    my $obj = $class->SUPER::new_factory(%args);
    $obj->{root} = $dir;
    return $obj;
}

sub validate_cfg {
    my ($class,%args) = @_;
    my $dir = delete $args{root};
    delete $args{ignore_parameters};
    my @err = $class->SUPER::validate_cfg(%args);
    if ( ! $dir ) {
	push @err, "no 'root' given";
    } elsif ( ! -d $dir || ! -r _ || ! -x _ ) {
	push @err, "cannot access root dir $dir";
    }
    return @err;
}

sub request_hdr {
    my ($self,$hdr) = @_;

    my ($method,$proto,$host,$path) = $hdr =~m{\A([A-Z]+) +(?:(\w+)://([^/]+))?(\S+)};
    $host = $1 if $hdr =~m{\nHost: *(\S+)}i;
    if ( ! $host ) {
	$self->run_callback([IMP_DENY,0,'cannot determine host']);
	return;
    }
    $proto ||= 'http';
    $host = lc($host);
    my $port =
        $host=~s{^(?:\[(\w._\-:)+\]|(\w._\-))(?::(\d+))?$}{ $1 || $2 }e ?
        $3:80;

    my $dir = $self->{factory_args}{root}."/$host:$port";
    goto IGNORE if ! -d $dir;

    my $uri = "$proto://$host:$port$path";
    my $qstring = $path =~s{\?(.+)}{} ? $1 : undef;
    # collect information to determine filename
    my %file = (
	uri => $uri,
        dir => $dir,
        method => $method,
        md5path => Digest::MD5->new->add($path)->hexdigest,
        md5data => undef,
    );

    my $fname = "$dir/".lc($method)."-".$file{md5path};
    goto TRY_FNAME if $self->{factory_args}{ignore_parameters};

    ( $file{md5data} = Digest::MD5->new )->add("\000$qstring\001")
        if defined $qstring;
    if ( $method ~~ [ 'GET','HEAD' ] ) {
	$fname .= "-".$file{md5data}->hexdigest if $file{md5data};
	goto TRY_FNAME;
    }

    # ignore if there will not be a matching filename, no matter
    # what md5data will be
    goto IGNORE if ! -f $fname and ! glob("$fname-*");

    # don't pass yet, continue in request body
    $file{rqhdr} = $hdr; 
    $self->{file} = \%file;
    return; 

    TRY_FNAME:
    if ( $self->{response} = _extract_response($fname)) {
	$hdr =~s{(\A\w+\s+)}{$1internal://};
	debug("hijack http://$host:$port$path");



( run in 1.072 second using v1.01-cache-2.11-cpan-d8267643d1d )