From: Joel Becker Date: Tue, 10 Jan 2006 06:32:47 GMT Subject: Re: undoing changes with git-checkout -f Message-ID: <20060110063247.GP18439@ca-server1.us.oracle.com> In-Reply-To: <7vk6d8aaln.fsf@assigned-by-dhcp.cox.net> On Mon, Jan 09, 2006 at 09:57:40PM -0800, Junio C Hamano wrote: > Joel Becker writes: > > Can we teach the git:// fetch program to use CONNECT over HTTP > > proxies? rsync can do this, but git:// cannot, so firewalls that block > > 9418 mean we use rsync:// > > I'm mostly offline this week or I'd take a stab at it. > > It's been there for quite some time, although I never liked the > way it interfaces with the outside world. > Ugly snipped... > It is a bit inconvenient that "git clone" wrapper cannot be used > on an existing repository, and without an existing repository > you cannot have .git/config. You could have the config file in > your site-wide template area, but admittably it is a bit > awkward. Here's what I did. I modified the usual ssh-tunnel-over-SSL-CONNECT script to honor http_proxy. I've attached it. With this, I do as so: # cp git-tunnel.pl /usr/local/bin # export http_proxy="http://my-proxy.my.com:80/" # GIT_PROXY_COMMAND="/usr/local/bin/git-tunnel.pl" git clone git://git.kernel.org/pub/scm/... localsource # cd localsource # vi .git/config [core] gitproxy = /usr/local/bin/git-tunnel.pl This is working for me. I'd really rather have the tunneling code be part of connect.c, and have core.proxymethod=external use the current core.gitproxy method and core.proxymethod=http use $http_proxy. But this will suffice for now :-) Joel -- Life's Little Instruction Book #198 "Feed a stranger's expired parking meter." Joel Becker Principal Software Developer Oracle E-mail: joel.becker@oracle.com Phone: (650) 506-8127 #!/usr/bin/perl # # git-tunnel.pl # # Usage: git-tunnel.pl ssl-proxy port destination_host port # # This script can be used by git as a "core.gitproxy" to # traverse a www-proxy/firewall that supports the http CONNECT # command described in # http://home.netscape.com/newsref/std/tunneling_ssl.html # # It uses the http_proxy (or HTTP_PROXY) variable to determine the # proxy to connect to. Put the path to this script in the environment # variable GIT_PROXY_COMMAND, or better yet, insert the core.gitproxy # definition in .git/config. # # . # . # [core] # gitproxy = /path/to/git-tunnel.pl # . # . # # Written by Urban Kaveus # Modified to use http_proxy by Joel Becker use Socket; # Parse command line arguments if ( $#ARGV != 1 ) { print STDERR "Usage: $0 destination port\n"; print STDERR $#ARGV, "\n"; exit(1); } $proxy_url = $ENV{'http_proxy'}; if (!$proxy_url) { $proxy_url = $ENV{'HTTP_PROXY'}; } $proxyport = 80; if ($proxy_url =~ /^https?:\/\/([^:]+)\/$/) { $sslproxy = $1; } elsif ($proxy_url =~ /^https?:\/\/([^:]+):([1-9][0-9]*)\/$/) { $sslproxy = $1; $proxyport = $2; } else { print STDERR "Invalid proxy specification: \"$proxy_url\"\n"; exit(1); } $destination = shift; $destport = shift; # Set up network communication ($protocol) = (getprotobyname("tcp"))[2]; ($proxyip) = (gethostbyname($sslproxy))[4]; $localaddr = pack('S n a4 x8', &AF_INET, 0, "\0\0\0\0"); $proxyaddr = pack('S n a4 x8', &AF_INET, $proxyport, $proxyip); socket (PROXY, &AF_INET, &SOCK_STREAM, $protocol) or die("Failed to create cocket"); bind (PROXY, $localaddr) or die("Failed to bind socket"); connect (PROXY, $proxyaddr) or die("Failed to connect to $sslproxy port $proxyport"); # Force flushing of socket buffers select (PROXY); $| = 1; select (STDOUT); $| = 1; # Send a "CONNECT" command to proxy: print PROXY "CONNECT $destination:$destport HTTP/1.1\r\n\r\n"; # Wait for HTTP status code, bail out if you don't get back a 2xx code. $_ = ; ($status) = (split())[1]; die("Received a bad status code \"$status\" from proxy server") if ( int($status/100) != 2 ); # Skip through remaining part of MIME header while() { chomp; # Strip last if /^[\r]*$/; # Empty line or a single left } # Start copying packets in both directions. if($child = fork) { # Parent process while (sysread(STDIN,$_,4096)) { print PROXY; } sleep 2; kill(15,$child) if $child; } else { # Child process while (sysread(PROXY,$_,4096)) { print STDOUT; } }