#!/usr/bin/perl use POSIX; use FileHandle; use vars qw($remwrite $remread); $remwrite = FileHandle->new(">&=7") or die "Error preparing remote write: $!\n"; $remread = FileHandle->new("<&=6") or die "Error preparing remote read: $!\n"; $remwrite->autoflush(1); $| = 1; my $firstline = 1; my $method; while (<>) { print STDERR "http_via: read line\n"; if ($firstline) { ($method)=/^(\S+)/; undef $firstline; print STDERR "http_via: Method is $method\n"; } if ($_ =~ /^[\r\n]*$/) { print STDERR "http_via: line was blank\n"; if ($ENV{HTTP_VIA}) { print $remwrite "Via: $ENV{VIA}\r\n"; } if ($ENV{TCPREMOTEIP}) { print $remwrite "X-Forwarded-For: ",$ENV{TCPREMOTEIP},"\r\n"; } if ($ENV{SSLPROXY}) { print $remwrite "X-Proxied-SSL: on\r\n"; } print $remwrite "\r\n"; last; } elsif (/^connection:/i) { print STDERR "http_via: Fixed up connection line!\n"; $_ = "Connection: close\r\n"; } print $remwrite $_; } if (!$method || ($method !~ /^post$/i)) { print STDERR "http_via: Done reading from client, reading from server...\n"; while (<$remread>) { print STDERR "http_via: read line from server\n"; if ($_ =~ /^[\r\n]*$/) { print STDERR "http_via: server line was blank\n"; print "\r\n"; last; } elsif (/^(location|uri):/i) { print STDERR "http_via: Fixed up location/URI line!\n"; s/http:/https:/i; } elsif (/^connection:/i) { print STDERR "http_via: Fixed up connection line!\n"; $_ = "Connection: close\r\n"; } print; } } &proxy($remread,$remwrite); sub proxy { warn "Starting proxy!\n"; my($r,$w)=@_; my($rin,$win,$ein); my($rout,$wout,$eout); my $nfound; my($rbufend,$wbufend); my($rembuf,$locbuf); my($remdone,$locdone); my $ret; $rembuf = $locbuf = ''; while (!( ($remdone || $locdone) && (!length($rembuf) && !length($locbuf) ) )) { $rin=$win=$ein=''; if (length($locbuf) > 0) { vec($win,fileno($w),1) = 1; } else { vec($rin,fileno(STDIN),1) = 1; } if (length($rembuf) > 0) { vec($win,fileno(STDOUT),1) = 1; } else { vec($rin,fileno($r),1) = 1; } $ein = $rin | $win; $nfound = select($rout=$rin,$wout=$win,$eout=$ein,86400); if ($nfound == 0) { die "Select error\n"; } if (length($locbuf)) { if (vec($wout,fileno($w),1)) { my $sofar = 0; my $howmuch; while ($sofar < length($locbuf)) { $howmuch = syswrite($w,$locbuf,length($locbuf)-$sofar,$sofar); if ($howmuch <= 0) { die "syswrite error\n"; } $sofar += $howmuch; } $locbuf = ''; } } else { if (vec($rout,fileno(STDIN),1)) { if (($ret=read(STDIN,$locbuf,8192)) <= 0) { if (!defined($ret)) { die "read error\n"; } elsif ($ret == 0) { $locdone = 1; } } } } if (length($rembuf)) { if (vec($wout,fileno(STDOUT),1)) { my $sofar = 0; my $howmuch; while ($sofar < length($rembuf)) { $howmuch = syswrite(STDOUT,$rembuf,length($rembuf)-$sofar,$sofar); if ($howmuch <= 0) { die "syswrite error\n"; } $sofar += $howmuch; } $rembuf = ''; } } else { if (vec($rout,fileno($r),1)) { if (($ret=read($r,$rembuf,8192)) <= 0) { if (!defined($ret)) { die "read error\n"; } elsif ($ret == 0) { $remdone = 1; } } } } } }