diff options
| author | Patrick Steinhardt <ps@pks.im> | 2025-05-12 11:19:57 +0200 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-05-12 10:55:46 -0700 |
| commit | 1248fb08d7e87911487fefb9f514d39eb5f4ddcb (patch) | |
| tree | eca8ea85cda53de7bdb1a7ba8730858f3572abab /contrib/persistent-https/proxy.go | |
| parent | contrib: remove "mw-to-git" (diff) | |
| download | git-1248fb08d7e87911487fefb9f514d39eb5f4ddcb.tar.gz git-1248fb08d7e87911487fefb9f514d39eb5f4ddcb.zip | |
contrib: remove "persistent-https" remote helper
The "persistent-https" remote helper supposedly speeds up SSL operations
by running a daemon that keeps a connection open to a remote server. It
is effectively unmaintained nowadays: the last time it received an
update was in accb613afd2 (contrib/persistent-https: use Git version for
build label, 2016-07-20) and its parent commits to make it compile with
Go 1.7+.
This Go toolchain is somewhat dated by now though and unsupported. The
oldest still-supported toolchain is Go 1.23, which was released in
August 2024. It is not possible to compile the remote helper with that
Go version anymore:
$ go version
go version go1.23.8 linux/amd64
$ make
case $(go version) in \
"go version go"1.[0-5].*) EQ=" " ;; *) EQ="=" ;; esac && \
go build -o git-remote-persistent-https \
-ldflags "-X main._BUILD_EMBED_LABEL${EQ}GIT_VERSION=2.49.0.943.g965a70ebf62"
go: cannot find main module, but found .git/config in /home/pks/Development/git
to create a module there, run:
cd ../.. && go mod init
make: *** [Makefile:31: git-remote-persistent-https] Error 1
The problem is that modern Go toolchains require a "go.mod" file, but we
don't have any such files. This requirement exists since quite a while
already, so it's clear that nobody has tried to use this remote helper
anytime recent.
Remove the remote helper.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'contrib/persistent-https/proxy.go')
| -rw-r--r-- | contrib/persistent-https/proxy.go | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/contrib/persistent-https/proxy.go b/contrib/persistent-https/proxy.go deleted file mode 100644 index bb0cdba386..0000000000 --- a/contrib/persistent-https/proxy.go +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2012 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "fmt" - "log" - "net" - "net/http" - "net/http/httputil" - "os" - "os/exec" - "os/signal" - "sync" - "syscall" - "time" -) - -type Proxy struct { - BuildLabel string - MaxIdleDuration time.Duration - PollUpdateInterval time.Duration - - ul net.Listener - httpAddr string - httpsAddr string -} - -func (p *Proxy) Run() error { - hl, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return fmt.Errorf("http listen failed: %v", err) - } - defer hl.Close() - - hsl, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return fmt.Errorf("https listen failed: %v", err) - } - defer hsl.Close() - - p.ul, err = DefaultSocket.Listen() - if err != nil { - c, derr := DefaultSocket.Dial() - if derr == nil { - c.Close() - fmt.Println("OK\nA proxy is already running... exiting") - return nil - } else if e, ok := derr.(*net.OpError); ok && e.Err == syscall.ECONNREFUSED { - // Nothing is listening on the socket, unlink it and try again. - syscall.Unlink(DefaultSocket.Path()) - p.ul, err = DefaultSocket.Listen() - } - if err != nil { - return fmt.Errorf("unix listen failed on %v: %v", DefaultSocket.Path(), err) - } - } - defer p.ul.Close() - go p.closeOnSignal() - go p.closeOnUpdate() - - p.httpAddr = hl.Addr().String() - p.httpsAddr = hsl.Addr().String() - fmt.Printf("OK\nListening on unix socket=%v http=%v https=%v\n", - p.ul.Addr(), p.httpAddr, p.httpsAddr) - - result := make(chan error, 2) - go p.serveUnix(result) - go func() { - result <- http.Serve(hl, &httputil.ReverseProxy{ - FlushInterval: 500 * time.Millisecond, - Director: func(r *http.Request) {}, - }) - }() - go func() { - result <- http.Serve(hsl, &httputil.ReverseProxy{ - FlushInterval: 500 * time.Millisecond, - Director: func(r *http.Request) { - r.URL.Scheme = "https" - }, - }) - }() - return <-result -} - -type socketContext struct { - sync.WaitGroup - mutex sync.Mutex - last time.Time -} - -func (sc *socketContext) Done() { - sc.mutex.Lock() - defer sc.mutex.Unlock() - sc.last = time.Now() - sc.WaitGroup.Done() -} - -func (p *Proxy) serveUnix(result chan<- error) { - sockCtx := &socketContext{} - go p.closeOnIdle(sockCtx) - - var err error - for { - var uconn net.Conn - uconn, err = p.ul.Accept() - if err != nil { - err = fmt.Errorf("accept failed: %v", err) - break - } - sockCtx.Add(1) - go p.handleUnixConn(sockCtx, uconn) - } - sockCtx.Wait() - result <- err -} - -func (p *Proxy) handleUnixConn(sockCtx *socketContext, uconn net.Conn) { - defer sockCtx.Done() - defer uconn.Close() - data := []byte(fmt.Sprintf("%v\n%v", p.httpsAddr, p.httpAddr)) - uconn.SetDeadline(time.Now().Add(5 * time.Second)) - for i := 0; i < 2; i++ { - if n, err := uconn.Write(data); err != nil { - log.Printf("error sending http addresses: %+v\n", err) - return - } else if n != len(data) { - log.Printf("sent %d data bytes, wanted %d\n", n, len(data)) - return - } - if _, err := uconn.Read([]byte{0, 0, 0, 0}); err != nil { - log.Printf("error waiting for Ack: %+v\n", err) - return - } - } - // Wait without a deadline for the client to finish via EOF - uconn.SetDeadline(time.Time{}) - uconn.Read([]byte{0, 0, 0, 0}) -} - -func (p *Proxy) closeOnIdle(sockCtx *socketContext) { - for d := p.MaxIdleDuration; d > 0; { - time.Sleep(d) - sockCtx.Wait() - sockCtx.mutex.Lock() - if d = sockCtx.last.Add(p.MaxIdleDuration).Sub(time.Now()); d <= 0 { - log.Println("graceful shutdown from idle timeout") - p.ul.Close() - } - sockCtx.mutex.Unlock() - } -} - -func (p *Proxy) closeOnUpdate() { - for { - time.Sleep(p.PollUpdateInterval) - if out, err := exec.Command(os.Args[0], "--print_label").Output(); err != nil { - log.Printf("error polling for updated binary: %v\n", err) - } else if s := string(out[:len(out)-1]); p.BuildLabel != s { - log.Printf("graceful shutdown from updated binary: %q --> %q\n", p.BuildLabel, s) - p.ul.Close() - break - } - } -} - -func (p *Proxy) closeOnSignal() { - ch := make(chan os.Signal, 10) - signal.Notify(ch, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM), os.Signal(syscall.SIGHUP)) - sig := <-ch - p.ul.Close() - switch sig { - case os.Signal(syscall.SIGHUP): - log.Printf("graceful shutdown from signal: %v\n", sig) - default: - log.Fatalf("exiting from signal: %v\n", sig) - } -} |
