App-HTTP_Proxy_IMP
view release on metacpan or search on metacpan
lib/App/HTTP_Proxy_IMP/Request.pm view on Meta::CPAN
$self->{conn}->in(1,"HTTP/1.0 200 Connection established\r\n\r\n");
return _call_spooled_this($self->{conn});
}
if ( my $imp = $self->{imp_analyzer} ) {
my $debug = $DEBUG && debug_context( id => $self->id);
if ( $imp->fixup_request_header(\$hdr, defered => 0) ) {
$self->{defer_rqhdr} = '';
} else {
# keep deferring sending header, length not known
_call_spooled_this($self->{conn}); # any body already ?
return;
}
}
my $relay = $self->{conn}{relay} or return;
$relay->forward(0,1,$hdr) if $self->{connected} == CONN_HOST;
_call_spooled_this($self->{conn}); # any body already ?
}
sub _call_spooled_this {
my $conn = shift;
# call spooled request_bodies, e.g. until we see a new request
debug("check for spooled subs in this request");
my $spool = $conn->{spool} or return;
$conn->{spool} = undef;
while (@$spool && ! $conn->{spool} ) {
my ($sub,@arg) = @{ $spool->[0] };
last if $sub == \&in_request_header;
shift(@$spool);
$DEBUG && debug("handle spooled event $sub");
$sub->(@arg);
}
push @{ $conn->{spool}}, @$spool if @$spool; # put back
}
sub _call_spooled_next {
my $conn = shift;
# skip until we have a next request, then continue
debug("check for spooled requests, ignoring subs for this");
my $spool = $conn->{spool} or return;
$conn->{spool} = undef;
while (@$spool) {
my ($sub,@arg) = @{ $spool->[0] };
last if $sub == \&in_request_header;
$DEBUG && debug("skip spooled event $sub");
shift(@$spool);
}
while (@$spool && ! $conn->{spool} ) {
my ($sub,@arg) = @{ $spool->[0] };
$DEBUG && debug("handle spooled event $sub");
$sub->(@arg);
}
push @{ $conn->{spool}}, @$spool if @$spool; # put back
}
############################################################################
# process request body data
# if IMP, we might need to wait for a callback to decide what to do with
# the data, otherwise the data are further send directly
# if IMP might modify the data, we need to defer sending the header to get
# the final content-length and fixup the header accordingly
############################################################################
sub in_request_body {
my ($self,$data,$eof) = @_;
my $conn = $self->{conn} or return;
my $relay = $conn->{relay} or return;
if ( ! $self->{connected} ) {
# not connected yet
$DEBUG && $self->xdebug("spool request body data");
push @{$conn->{spool}}, [ \&in_request_body, @_ ];
return;
}
$DEBUG && $self->xdebug("got request body data len=%d eof=%d",length($data),$eof);
my $imp = $self->{imp_analyzer};
if ( ! $imp ) {
# fast path w/o imp
$relay->forward(0,1,$data) if $data ne ''
and $self->{connected} == CONN_HOST;
return;
}
# feed data into IMP
$DEBUG && $self->xdebug("fwd request body to IMP");
my $debug = $DEBUG && debug_context( id => $self->id);
$imp->request_body($data,\&_request_body_after_imp,$self) if $data ne '';
$imp->request_body('',\&_request_body_after_imp,$self) if $eof;
}
############################################################################
# process request body data in case of IMP
# called from IMP callback working on request body data
############################################################################
sub _request_body_after_imp {
my ($self,$data,$eof) = @_;
my $conn = $self->{conn} or return;
my $relay = $conn->{relay} or return;
my $debug = $DEBUG && debug_context( id => $self->id);
if ( $self->{defer_rqhdr} ne '') {
$self->{defer_rqbody} .= $data;
if ( not $self->{imp_analyzer}->fixup_request_header(
\$self->{defer_rqhdr},
defered => length($self->{defer_rqbody})
)) {
# body length still not known
$DEBUG && debug("request body length still unknown");
$self->{defer_rqbody} .= $data;
$eof or return;
}
$DEBUG && debug("forward %d bytes header + %d bytes body",
length($self->{defer_rqhdr}),
length($self->{defer_rqbody}));
$relay->forward(0,1,$self->{defer_rqhdr}.$self->{defer_rqbody} )
if $self->{connected} == CONN_HOST;
lib/App/HTTP_Proxy_IMP/Request.pm view on Meta::CPAN
$relay->forward(1,0,$data);
}
if ($eof) {
$relay->account('request');
if ( ! $self->{keep_alive} ) {
# close connection
$DEBUG && $self->xdebug("end of request: close");
return $relay->close;
}
# keep connection open
# and continue with next request if we have one
$DEBUG && $self->xdebug("end of request: keep-alive");
_call_spooled_next( $self->{conn} );
}
}
############################################################################
# Websockets, TLS upgrades etc
# if not IMP the forwarding will be done inside this function, otherwise it
# will be done in _in_data_imp, which gets called by IMP callback
############################################################################
sub in_data {
my ($self,$dir,$data,$eof) = @_;
if ( my $imp = $self->{imp_analyzer} ) {
my $debug = $DEBUG && debug_context( id => $self->id);
$data ne '' and $imp->data($dir,$data,\&_in_data_imp,$self);
$eof and $imp->data($dir,'',\&_in_data_imp,$self);
} else {
my $relay = $self->{conn}{relay} or return;
$DEBUG && $self->xdebug("got %d bytes from %d, eof=%d",length($data),$dir,$eof);
if ( $data ne '' ) {
if ( $dir == 1 ) {
$relay->forward(1,0,$data)
} else {
$relay->forward(0,1,$data) if $self->{connected} == CONN_HOST;
}
}
$relay->account('upgrade') if $eof;
}
}
sub _in_data_imp {
my ($self,$dir,$data,$eof) = @_;
my $relay = $self->{conn}{relay} or return;
$DEBUG && $self->xdebug("imp got %d bytes from %d, eof=%d",length($data),$dir,$eof);
if ( $data ne '' ) {
if ( $dir == 1 ) {
$relay->forward(1,0,$data)
} else {
$relay->forward(0,1,$data) if $self->{connected} == CONN_HOST;
}
}
$relay->account('upgrade') if $eof;
}
############################################################################
# chunks and junk gets ignored
# - we decide ourself, when we will forward data chunked and do the
# chunking ourself
# - junk data will not be forwarded
############################################################################
sub in_chunk_header {}
sub in_chunk_trailer {}
sub in_junk {}
1;
( run in 2.527 seconds using v1.01-cache-2.11-cpan-e93a5daba3e )