Skip to content

Commit 73bcf53

Browse files
iarenazaJunio C Hamano
authored andcommitted
git-cvsimport: add support for CVS pserver method HTTP/1.x proxying
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7182135 commit 73bcf53

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

git-cvsimport.perl

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,22 @@ sub new {
161161
sub conn {
162162
my $self = shift;
163163
my $repo = $self->{'fullrep'};
164-
if($repo =~ s/^:pserver:(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) {
165-
my($user,$pass,$serv,$port) = ($1,$2,$3,$4);
164+
if($repo =~ s/^:pserver(?:([^:]*)):(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) {
165+
my($param,$user,$pass,$serv,$port) = ($1,$2,$3,$4,$5);
166+
167+
my($proxyhost,$proxyport);
168+
if($param && ($param =~ m/proxy=([^;]+)/)) {
169+
$proxyhost = $1;
170+
# Default proxyport, if not specified, is 8080.
171+
$proxyport = 8080;
172+
if($ENV{"CVS_PROXY_PORT"}) {
173+
$proxyport = $ENV{"CVS_PROXY_PORT"};
174+
}
175+
if($param =~ m/proxyport=([^;]+)/){
176+
$proxyport = $1;
177+
}
178+
}
179+
166180
$user="anonymous" unless defined $user;
167181
my $rr2 = "-";
168182
unless($port) {
@@ -187,13 +201,43 @@ sub conn {
187201
}
188202
$pass="A" unless $pass;
189203

190-
my $s = IO::Socket::INET->new(PeerHost => $serv, PeerPort => $port);
191-
die "Socket to $serv: $!\n" unless defined $s;
204+
my ($s, $rep);
205+
if($proxyhost) {
206+
207+
# Use a HTTP Proxy. Only works for HTTP proxies that
208+
# don't require user authentication
209+
#
210+
# See: http://www.ietf.org/rfc/rfc2817.txt
211+
212+
$s = IO::Socket::INET->new(PeerHost => $proxyhost, PeerPort => $proxyport);
213+
die "Socket to $proxyhost: $!\n" unless defined $s;
214+
$s->write("CONNECT $serv:$port HTTP/1.1\r\nHost: $serv:$port\r\n\r\n")
215+
or die "Write to $proxyhost: $!\n";
216+
$s->flush();
217+
218+
$rep = <$s>;
219+
220+
# The answer should look like 'HTTP/1.x 2yy ....'
221+
if(!($rep =~ m#^HTTP/1\.. 2[0-9][0-9]#)) {
222+
die "Proxy connect: $rep\n";
223+
}
224+
# Skip up to the empty line of the proxy server output
225+
# including the response headers.
226+
while ($rep = <$s>) {
227+
last if (!defined $rep ||
228+
$rep eq "\n" ||
229+
$rep eq "\r\n");
230+
}
231+
} else {
232+
$s = IO::Socket::INET->new(PeerHost => $serv, PeerPort => $port);
233+
die "Socket to $serv: $!\n" unless defined $s;
234+
}
235+
192236
$s->write("BEGIN AUTH REQUEST\n$repo\n$user\n$pass\nEND AUTH REQUEST\n")
193237
or die "Write to $serv: $!\n";
194238
$s->flush();
195239

196-
my $rep = <$s>;
240+
$rep = <$s>;
197241

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

0 commit comments

Comments
 (0)