From 859fb2118792953250d73425b4bd343e817c60bd Mon Sep 17 00:00:00 2001 From: b Date: Mon, 16 Nov 2015 18:43:40 +0000 Subject: [PATCH] The proxy is archiving now! git-svn-id: svn://botcastle1b/yplom/proxy@9 05ce6ebb-7522-4a6e-a768-0026ae12be9f --- configure.pl | 1 + proxy.1.pl | 378 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 302 insertions(+), 77 deletions(-) diff --git a/configure.pl b/configure.pl index b4a7b39..3fcd1e7 100755 --- a/configure.pl +++ b/configure.pl @@ -27,6 +27,7 @@ $def{'CURL_PATH'} = "use constant CURL_PATH => '".$set{'curl'}. $def{'DATA_PATH'} = "use constant DATA_PATH => '".$set{'data_path'}."';"; $def{'TEMP_PATH'} = "use constant TEMP_PATH => '".$set{'tmp_path'}."';"; $def{'PASS_PATH'} = "use constant PASS_PATH => '".$set{'data_path'}."pass/';"; +$def{'ARCH_PATH'} = "use constant ARCH_PATH => '".$set{'data_path'}."archive/';"; $def{'ACCESS_PATH'} = "use constant ACCESS_PATH => '".$set{'data_path'}."access/';"; $def{'UNLOCK_PROXY_URL'} = "use constant UNLOCK_PROXY_URL => 'http://".$set{'unlock_domain'}.$set{'unlock_path'}."';"; $def{'UNLOCK_PROXY_URL_S'}= "use constant UNLOCK_PROXY_URL_S => 'https://".$set{'unlock_domain'}.$set{'unlock_path'}."';"; diff --git a/proxy.1.pl b/proxy.1.pl index 236cabb..bf53924 100755 --- a/proxy.1.pl +++ b/proxy.1.pl @@ -6,6 +6,7 @@ use POSIX qw(strftime); ###UNLOCK_LOG; ###CURL_PATH; ###PASS_PATH; +###ARCH_PATH; ###ACCESS_PATH; ###UNLOCK_PROXY_URL; ###UNLOCK_PROXY_URL_S; @@ -39,7 +40,9 @@ else { } sub proxy { - srand(time()+$$); + # srand(time()+$$); + + $archive = 0; if ($ENV{'REQUEST_METHOD'} !~ /^(HEAD|GET|POST)$/) { return fail("Status: 405 Method Not Allowed\nAllow: GET, POST, HEAD\n","405 Method Not Allowed","The proxy does not support the $ENV{'REQUEST_METHOD'} method."); @@ -78,36 +81,15 @@ sub proxy { return fail("Status: 403 Forbidden\n","403 Forbidden","The proxy does not accept port number $port because of infinite loop prevention."); } - do { - $temppath=TEMP_PATH.int(rand(100000000)).'_'; - $headpath=$temppath.'h'; - $downpath=$temppath.'d'; - $uppath=$temppath.'u'; - } while (( -e $headpath) or ( -e $downpath) or ( -e $uppath)); + # do { + # $temppath=TEMP_PATH.int(rand(100000000)).'_'; + # $headpath=$temppath.'h'; + # $downpath=$temppath.'d'; + # $uppath=$temppath.'u'; + # } while (( -e $headpath) or ( -e $downpath) or ( -e $uppath)); @curl_arg=(CURL_PATH,'-i','-#'); #-s - - if ($ENV{'REQUEST_METHOD'} eq 'HEAD'){ - push @curl_arg, '-I'; - } - - if ($ENV{'REQUEST_METHOD'} eq 'POST'){ - binmode(STDIN) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to switch STDIN to binary mode."); - open($upfile,">",$uppath) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create temporary file."); - binmode ($upfile) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to switch temporary file to binary mode."); - - $buffer; - while (read (STDIN,$buffer,65536)) { - unless (print ($upfile $buffer)) { - return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to write to temporary file."); - } - } - close ($upfile); - $craetedup=1; - - push @curl_arg, '--data-binary'; - push @curl_arg, '@'.$uppath; - } + @reqhead; foreach $envk (keys %ENV) { if ($envk =~ /^(HTTP_[A-Z0-9_]+)$/) { @@ -133,6 +115,7 @@ sub proxy { push @curl_arg, '-H'; push @curl_arg, $headarg; + push @reqhead, $headarg; } unless (exists $ENV{'HTTP_USER_AGENT'}) { push @curl_arg, '-H'; @@ -143,29 +126,144 @@ sub proxy { push @curl_arg, 'ACCEPT:'; } + if ($ENV{'REQUEST_METHOD'} eq 'HEAD'){ + push @curl_arg, '-I'; + } + + if ($ENV{'REQUEST_METHOD'} eq 'POST'){ + # binmode(STDIN) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to switch STDIN to binary mode."); + # open($upfile,">",$uppath) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create temporary file."); + # binmode ($upfile) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to switch temporary file to binary mode."); + + # $buffer; + # while (read (STDIN,$buffer,65536)) { + # unless (print ($upfile $buffer)) { + # return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to write to temporary file."); + # } + # } + # close ($upfile); + # $craetedup=1; + + $postdata=1; + push @curl_arg, '--data-binary'; + # push @curl_arg, '@'.$uppath; + push @curl_arg, '@-'; + + } + + $archpath = makepath($prot, $host, $port, $path); + if ($archpath) { + $archive = 1; + if ($query or $postdata) { + for (my $i = 0; ;++$i) { + $respcontpath=$archpath.'@v-'.$i; + $respheadpath=$archpath.'@h-'.$i; + $postheadpath=$archpath.'@g-'.$i; + $postcontpath=$archpath.'@u-'.$i; + $postquerpath=$archpath.'@q-'.$i; + + if ((! -e $respcontpath) and (! -e $respheadpath) and (! -e $postheadpath) and (! -e $postcontpath) and (! -e $postquerpath)) { + last; + } + } + + if ($query) { + if (open ($postquerfile, ">", $postquerpath)) { + print $postquerfile "$query\n"; + close($postquerfile); + } + } + + if ($postdata) { + if (open ($postheadfile, ">", $postheadpath)) { + foreach $line (@reqhead) { + print $postheadfile "$line\n"; + } + print $postheadfile "$line\n"; + close ($postheadfile); + } + } + } + else { + $respcontpath=$archpath.'@v'; + $respheadpath=$archpath.'@h'; + $postheadpath=''; + $postcontpath=''; + $postquerpath=''; + } + } + else { + $archive = 0; + } + push @curl_arg, $URL; - pipe ($STDREAD, $STDWRITE) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create stdout pipe."); - pipe ($ERRREAD, $ERRWRITE) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create stderr pipe."); + pipe ($curloutrd, $curloutwr) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create stdout pipe."); + pipe ($curlerrrd, $curlerrwr) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create stderr pipe."); + if ($postdata){ + pipe ($curlinrd, $curlinwr) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create stdin pipe."); + } $curlpid = fork(); unless (defined $curlpid) { return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","fork() failed."); } unless ($curlpid) { - close ($STDREAD); - close ($ERRREAD); + close ($curloutrd); + close ($curlerrrd); - open(STDERR, ">&=" . fileno($ERRWRITE)) or die "Failed to open stderr pipe.\n"; - open(STDOUT, ">&=" . fileno($STDWRITE)) or die "Failed to open stdout pipe.\n"; + open(STDERR, ">&=" . fileno($curlerrwr)) or die "Failed to open stderr pipe.\n"; + open(STDOUT, ">&=" . fileno($curloutwr)) or die "Failed to open stdout pipe.\n"; + + if ($postdata) { + close ($curlinwr); + open(STDIN, "<&=" . fileno($curlinrd)) or die "Failed to open stdin pipe.\n"; + } exec @curl_arg; exit 1; } - close ($STDWRITE); - close ($ERRWRITE); + close ($curloutwr); + close ($curlerrwr); + if($postdata) { + # $curlpidin = fork(); + # unless (defined $curlpidin) { + # $forceexit=1; + # } + # unless ($curlpidin) { + close($curlinrd); + binmode($curlinwr) or die "Failed to switch stdin pipe to binary mode.\n"; + binmode(STDIN) or die "Failed to switch STDIN to binary mode.\n"; + + $buffer2; + + $postcontopen = open($postcontfile, ">", $postcontpath); + if ($postcontopen){ + unless (binmode($postcontfile)) { + close($postcontfile); + $postcontopen=0; + } + } + + while (read (STDIN,$buffer2,1024)) { + unless (print ($curlinwr $buffer2)) { + #$forceexit = 1; + } + if ($postcontopen) { + print $postcontfile $buffer2; + } + } + close ($curlinwr); + if ($postcontopen) { + close($postcontfile); + } + # exit 0; + # } + # close ($curinwr); + # close ($curlinrd); + } $safelength=1; $definedlength=0; @@ -173,11 +271,17 @@ sub proxy { $lastskipped=1; $forceexit=0; - if ($line = <$STDREAD>) { + if ($line = <$curloutrd>) { $line =~ s/\r?\n$//; if ($line =~ /^HTTP\/[0-9]+\.[0-9]+ ([0-9]+ .*)$/) { - @resphead=('Status: '.$1); - while ($line = <$STDREAD>) { + $status =$1; + @resphead=('Status: '.$status); + + if(($status !~ /^2[0-9][0-9]/) and (-e $respcontpath)){ + $archive=0; + } + + while ($line = <$curloutrd>) { $line =~ s/[\r\n]$//g; if($line eq ''){ @@ -231,32 +335,56 @@ sub proxy { push @resphead, 'Content-length: '.$contentlength; } - #! write this to file (h) too ! { $safeerror=0; + + if ($archive) { + $respheadopen = open($respheadfile, ">", $respheadpath); + } foreach $line (@resphead) { print $line."\n"; + if($respheadopen) { + print $respheadfile $line."\n"; + } } print "\n"; - #! } + if($respheadopen) { + print $respheadfile "\n"; + close $respheadfile; + } - if ( ! binmode ($STDREAD)) { - print "FAIL 1\n"; + if ( ! binmode ($curloutrd)) { + # print "FAIL 1\n"; $forceexit=1; } elsif ( ! binmode (STDOUT) ) { - print "FAIL 2\n"; + # print "FAIL 2\n"; $forceexit=1; } else { - - #! write this to file (c) too ! { - while (read ($STDREAD,$buffer,65536)) { + $firstline=1; + while (read ($curloutrd,$buffer,1024)) { unless (print (STDOUT $buffer)) { $forceexit=1; - next; + } + if ($firstline) { + if ($archive) { + $respcontopen = open($respcontfile, ">", $respcontpath); + } + if ($respcontopen){ + unless (binmode($respcontfile)) { + close($respcontfile); + $respcontopen=0; + } + } + } + $firstline=0; + if ($respcontopen) { + print $respcontfile $buffer; } } - #! } + if($respcontopen) { + close ($respcontfile); + } } } else { @@ -265,15 +393,11 @@ sub proxy { } - # print "Content-type: text/plain\n\n"; - - # print"\n"; - waitpid($curlpid,0); if ($? != 0) { if ($safeerror) { $errormsg=''; - while ($line = <$ERRREAD>) { + while ($line = <$curlerrrd>) { $line =~ s/\r?\n/
/g; $errormsg=$errormsg.$line; } @@ -282,12 +406,15 @@ sub proxy { $forceexit=1; } } - close(STDREAD); - close(ERRREAD); + close($curloutrd); + close($curlerrrd); - if ($createdup) { - unlink $uppath; - } + # if ($postdata) { + # waitpid($curlpidin,0); + # if ($? != 0) { + # $forceexit=1; + # } + # } if($safeerror){ return fail("Status: 500 Internal Server Error\n","500 Internal Server Error",$errormsg); @@ -296,21 +423,6 @@ sub proxy { exit 1; } - # print "host: $host\nport: $port\n\n"; - # foreach $yyyb (@curl_arg) { - # print "$yyyb\n"; - # } - # #print "\n".(system @curl_arg)."\n"; - - # unlink $headpath; - # unlink $downpath; - # unlink $uppath; - - - # print "\nDEBUGINFO:\n"; - - # return debag(); - } sub access { #kind of doubles the functionality of access.pl but for http @@ -580,7 +692,7 @@ sub debag { sub validateurl { my $url = $_[0]; - my $prot; + $prot; my $hostportpathquery; my $hostportpath; $query; @@ -626,7 +738,7 @@ sub validateurl { if ($path !~ /^((%[0-9A-Fa-f][0-9A-Fa-f])|([A-Za-z0-9:;@&=\+\$\,-_\.~\*'\(\)]))*$/) { return 0; } - + $path=urldecode($path); } else { $hostport = $hostportpath; @@ -648,3 +760,115 @@ sub validateurl { return 1; } + +sub makepath { + #inspired by the MIRA browser! + (my $prot, my $host, my $port, my $path) = @_; + + my $archpath = ARCH_PATH; + + if ($prot =~ /^(https?)$/) { + $archpath .= $1; + } + else { + return ''; + } + + if ($port =~ /^([0-9]+)$/) { + $archpath .= "\@p$1"; + } + + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + + if($host =~ /^([A-Za-z0-9\-\.]+)$/) { + $host = $1; + } + else { + return ''; + } + + while ((my $ind = rindex ($host, '.'))>=0) { + my $part= substr $host, $ind+1; + $host = substr $host, 0, $ind; + + while (length ($part) > 120) { + $archpath .= '/'.substr($part,0,64).'-'; + $part = substr($part,64); + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + } + $archpath .= '/'.$part; + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + } + while (length ($host) > 120) { + $archpath .= '/'.substr($host,0,64).'-'; + $host = substr($host,64); + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + } + $archpath .= '/'.$host.'@n'; + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + + $path =~ s/^\///; + + while ((my $ind = index ($path, '/'))>=0) { + my $part = substr $path, 0, $ind; + $path= substr $path, $ind+1; + + $part =~ s/[^A-Za-z0-9_\.]/sprintf ("@%02X",ord($1))/eg; + + while (length ($part) > 120) { + $archpath .= '/'.substr($part,0,64).'-'; + $part = substr($part,64); + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + } + $archpath .= '/'.$part; + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + } + $path =~ s/[^A-Za-z0-9_\.]/sprintf ("@%02X",ord($1))/eg; + while (length ($path) > 120) { + $archpath .= '/'.substr($path,0,64).'-'; + $path = substr($path,64); + unless (-d $archpath) + { + unless (mkdir $archpath) { + return ''; + } + } + } + $archpath .= '/'.$path; + return $archpath; +} -- 2.30.2