Skip to content

Commit

Permalink
git-cvsimport: add support for CVS pserver method HTTP/1.x proxying
Browse files Browse the repository at this point in the history
This patch adds support for 'proxy' and 'proxyport' connection options
when using the pserver method for the CVS Root.

It has been tested with a Squid 2.5.x proxy server.

Quoting from the CVS info manual:

     The `gserver' and `pserver' connection methods all accept optional
  method options, specified as part of the METHOD string, like so:

       :METHOD[;OPTION=ARG...]:

     Currently, the only two valid connection options are `proxy', which
  takes a hostname as an argument, and `proxyport', which takes a port
  number as an argument.  These options can be used to connect via an HTTP
  tunnel style web proxy.  For example, to connect pserver via a web proxy
  at www.myproxy.net and port 8000, you would use a method of:

       :pserver;proxy=www.myproxy.net;proxyport=8000:

     *NOTE: The rest of the connection string is required to connect to
  the server as noted in the upcoming sections on password authentication,
  gserver and kserver.  The example above would only modify the METHOD
  portion of the repository name.*

     PROXY must be supplied to connect to a CVS server via a proxy
  server, but PROXYPORT will default to port 8080 if not supplied.
  PROXYPORT may also be set via the CVS_PROXY_PORT environment variable.

Signed-off-by: Iñaki Arenaza <iarenuno@eteo.mondragon.edu>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Iñaki Arenaza authored and Junio C Hamano committed Nov 24, 2006
1 parent 7182135 commit 73bcf53
Showing 1 changed file with 49 additions and 5 deletions.
54 changes: 49 additions & 5 deletions git-cvsimport.perl
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,22 @@ sub new {
sub conn {
my $self = shift;
my $repo = $self->{'fullrep'};
if($repo =~ s/^:pserver:(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) {
my($user,$pass,$serv,$port) = ($1,$2,$3,$4);
if($repo =~ s/^:pserver(?:([^:]*)):(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) {
my($param,$user,$pass,$serv,$port) = ($1,$2,$3,$4,$5);

my($proxyhost,$proxyport);
if($param && ($param =~ m/proxy=([^;]+)/)) {
$proxyhost = $1;
# Default proxyport, if not specified, is 8080.
$proxyport = 8080;
if($ENV{"CVS_PROXY_PORT"}) {
$proxyport = $ENV{"CVS_PROXY_PORT"};
}
if($param =~ m/proxyport=([^;]+)/){
$proxyport = $1;
}
}

$user="anonymous" unless defined $user;
my $rr2 = "-";
unless($port) {
Expand All @@ -187,13 +201,43 @@ sub conn {
}
$pass="A" unless $pass;

my $s = IO::Socket::INET->new(PeerHost => $serv, PeerPort => $port);
die "Socket to $serv: $!\n" unless defined $s;
my ($s, $rep);
if($proxyhost) {

# Use a HTTP Proxy. Only works for HTTP proxies that
# don't require user authentication
#
# See: http://www.ietf.org/rfc/rfc2817.txt

$s = IO::Socket::INET->new(PeerHost => $proxyhost, PeerPort => $proxyport);
die "Socket to $proxyhost: $!\n" unless defined $s;
$s->write("CONNECT $serv:$port HTTP/1.1\r\nHost: $serv:$port\r\n\r\n")
or die "Write to $proxyhost: $!\n";
$s->flush();

$rep = <$s>;

# The answer should look like 'HTTP/1.x 2yy ....'
if(!($rep =~ m#^HTTP/1\.. 2[0-9][0-9]#)) {
die "Proxy connect: $rep\n";
}
# Skip up to the empty line of the proxy server output
# including the response headers.
while ($rep = <$s>) {
last if (!defined $rep ||
$rep eq "\n" ||
$rep eq "\r\n");
}
} else {
$s = IO::Socket::INET->new(PeerHost => $serv, PeerPort => $port);
die "Socket to $serv: $!\n" unless defined $s;
}

$s->write("BEGIN AUTH REQUEST\n$repo\n$user\n$pass\nEND AUTH REQUEST\n")
or die "Write to $serv: $!\n";
$s->flush();

my $rep = <$s>;
$rep = <$s>;

if($rep ne "I LOVE YOU\n") {
$rep="<unknown>" unless $rep;
Expand Down

0 comments on commit 73bcf53

Please sign in to comment.