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>

Patrick Steinhardt committed May 12, 2025 at 11:19 UTC 1248fb08d7e87911487fefb9f514d39eb5f4ddcb
7 files changed -875
contrib/persistent-https/LICENSE deleted
-202
@@ -1,202 +0,0 @@
1 -
2 - Apache License
3 - Version 2.0, January 2004
4 - http://www.apache.org/licenses/
5 -
6 - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 -
8 - 1. Definitions.
9 -
10 - "License" shall mean the terms and conditions for use, reproduction,
11 - and distribution as defined by Sections 1 through 9 of this document.
12 -
13 - "Licensor" shall mean the copyright owner or entity authorized by
14 - the copyright owner that is granting the License.
15 -
16 - "Legal Entity" shall mean the union of the acting entity and all
17 - other entities that control, are controlled by, or are under common
18 - control with that entity. For the purposes of this definition,
19 - "control" means (i) the power, direct or indirect, to cause the
20 - direction or management of such entity, whether by contract or
21 - otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 - outstanding shares, or (iii) beneficial ownership of such entity.
23 -
24 - "You" (or "Your") shall mean an individual or Legal Entity
25 - exercising permissions granted by this License.
26 -
27 - "Source" form shall mean the preferred form for making modifications,
28 - including but not limited to software source code, documentation
29 - source, and configuration files.
30 -
31 - "Object" form shall mean any form resulting from mechanical
32 - transformation or translation of a Source form, including but
33 - not limited to compiled object code, generated documentation,
34 - and conversions to other media types.
35 -
36 - "Work" shall mean the work of authorship, whether in Source or
37 - Object form, made available under the License, as indicated by a
38 - copyright notice that is included in or attached to the work
39 - (an example is provided in the Appendix below).
40 -
41 - "Derivative Works" shall mean any work, whether in Source or Object
42 - form, that is based on (or derived from) the Work and for which the
43 - editorial revisions, annotations, elaborations, or other modifications
44 - represent, as a whole, an original work of authorship. For the purposes
45 - of this License, Derivative Works shall not include works that remain
46 - separable from, or merely link (or bind by name) to the interfaces of,
47 - the Work and Derivative Works thereof.
48 -
49 - "Contribution" shall mean any work of authorship, including
50 - the original version of the Work and any modifications or additions
51 - to that Work or Derivative Works thereof, that is intentionally
52 - submitted to Licensor for inclusion in the Work by the copyright owner
53 - or by an individual or Legal Entity authorized to submit on behalf of
54 - the copyright owner. For the purposes of this definition, "submitted"
55 - means any form of electronic, verbal, or written communication sent
56 - to the Licensor or its representatives, including but not limited to
57 - communication on electronic mailing lists, source code control systems,
58 - and issue tracking systems that are managed by, or on behalf of, the
59 - Licensor for the purpose of discussing and improving the Work, but
60 - excluding communication that is conspicuously marked or otherwise
61 - designated in writing by the copyright owner as "Not a Contribution."
62 -
63 - "Contributor" shall mean Licensor and any individual or Legal Entity
64 - on behalf of whom a Contribution has been received by Licensor and
65 - subsequently incorporated within the Work.
66 -
67 - 2. Grant of Copyright License. Subject to the terms and conditions of
68 - this License, each Contributor hereby grants to You a perpetual,
69 - worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 - copyright license to reproduce, prepare Derivative Works of,
71 - publicly display, publicly perform, sublicense, and distribute the
72 - Work and such Derivative Works in Source or Object form.
73 -
74 - 3. Grant of Patent License. Subject to the terms and conditions of
75 - this License, each Contributor hereby grants to You a perpetual,
76 - worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 - (except as stated in this section) patent license to make, have made,
78 - use, offer to sell, sell, import, and otherwise transfer the Work,
79 - where such license applies only to those patent claims licensable
80 - by such Contributor that are necessarily infringed by their
81 - Contribution(s) alone or by combination of their Contribution(s)
82 - with the Work to which such Contribution(s) was submitted. If You
83 - institute patent litigation against any entity (including a
84 - cross-claim or counterclaim in a lawsuit) alleging that the Work
85 - or a Contribution incorporated within the Work constitutes direct
86 - or contributory patent infringement, then any patent licenses
87 - granted to You under this License for that Work shall terminate
88 - as of the date such litigation is filed.
89 -
90 - 4. Redistribution. You may reproduce and distribute copies of the
91 - Work or Derivative Works thereof in any medium, with or without
92 - modifications, and in Source or Object form, provided that You
93 - meet the following conditions:
94 -
95 - (a) You must give any other recipients of the Work or
96 - Derivative Works a copy of this License; and
97 -
98 - (b) You must cause any modified files to carry prominent notices
99 - stating that You changed the files; and
100 -
101 - (c) You must retain, in the Source form of any Derivative Works
102 - that You distribute, all copyright, patent, trademark, and
103 - attribution notices from the Source form of the Work,
104 - excluding those notices that do not pertain to any part of
105 - the Derivative Works; and
106 -
107 - (d) If the Work includes a "NOTICE" text file as part of its
108 - distribution, then any Derivative Works that You distribute must
109 - include a readable copy of the attribution notices contained
110 - within such NOTICE file, excluding those notices that do not
111 - pertain to any part of the Derivative Works, in at least one
112 - of the following places: within a NOTICE text file distributed
113 - as part of the Derivative Works; within the Source form or
114 - documentation, if provided along with the Derivative Works; or,
115 - within a display generated by the Derivative Works, if and
116 - wherever such third-party notices normally appear. The contents
117 - of the NOTICE file are for informational purposes only and
118 - do not modify the License. You may add Your own attribution
119 - notices within Derivative Works that You distribute, alongside
120 - or as an addendum to the NOTICE text from the Work, provided
121 - that such additional attribution notices cannot be construed
122 - as modifying the License.
123 -
124 - You may add Your own copyright statement to Your modifications and
125 - may provide additional or different license terms and conditions
126 - for use, reproduction, or distribution of Your modifications, or
127 - for any such Derivative Works as a whole, provided Your use,
128 - reproduction, and distribution of the Work otherwise complies with
129 - the conditions stated in this License.
130 -
131 - 5. Submission of Contributions. Unless You explicitly state otherwise,
132 - any Contribution intentionally submitted for inclusion in the Work
133 - by You to the Licensor shall be under the terms and conditions of
134 - this License, without any additional terms or conditions.
135 - Notwithstanding the above, nothing herein shall supersede or modify
136 - the terms of any separate license agreement you may have executed
137 - with Licensor regarding such Contributions.
138 -
139 - 6. Trademarks. This License does not grant permission to use the trade
140 - names, trademarks, service marks, or product names of the Licensor,
141 - except as required for reasonable and customary use in describing the
142 - origin of the Work and reproducing the content of the NOTICE file.
143 -
144 - 7. Disclaimer of Warranty. Unless required by applicable law or
145 - agreed to in writing, Licensor provides the Work (and each
146 - Contributor provides its Contributions) on an "AS IS" BASIS,
147 - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 - implied, including, without limitation, any warranties or conditions
149 - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 - PARTICULAR PURPOSE. You are solely responsible for determining the
151 - appropriateness of using or redistributing the Work and assume any
152 - risks associated with Your exercise of permissions under this License.
153 -
154 - 8. Limitation of Liability. In no event and under no legal theory,
155 - whether in tort (including negligence), contract, or otherwise,
156 - unless required by applicable law (such as deliberate and grossly
157 - negligent acts) or agreed to in writing, shall any Contributor be
158 - liable to You for damages, including any direct, indirect, special,
159 - incidental, or consequential damages of any character arising as a
160 - result of this License or out of the use or inability to use the
161 - Work (including but not limited to damages for loss of goodwill,
162 - work stoppage, computer failure or malfunction, or any and all
163 - other commercial damages or losses), even if such Contributor
164 - has been advised of the possibility of such damages.
165 -
166 - 9. Accepting Warranty or Additional Liability. While redistributing
167 - the Work or Derivative Works thereof, You may choose to offer,
168 - and charge a fee for, acceptance of support, warranty, indemnity,
169 - or other liability obligations and/or rights consistent with this
170 - License. However, in accepting such obligations, You may act only
171 - on Your own behalf and on Your sole responsibility, not on behalf
172 - of any other Contributor, and only if You agree to indemnify,
173 - defend, and hold each Contributor harmless for any liability
174 - incurred by, or claims asserted against, such Contributor by reason
175 - of your accepting any such warranty or additional liability.
176 -
177 - END OF TERMS AND CONDITIONS
178 -
179 - APPENDIX: How to apply the Apache License to your work.
180 -
181 - To apply the Apache License to your work, attach the following
182 - boilerplate notice, with the fields enclosed by brackets "[]"
183 - replaced with your own identifying information. (Don't include
184 - the brackets!) The text should be enclosed in the appropriate
185 - comment syntax for the file format. We also recommend that a
186 - file or class name and description of purpose be included on the
187 - same "printed page" as the copyright notice for easier
188 - identification within third-party archives.
189 -
190 - Copyright [yyyy] [name of copyright owner]
191 -
192 - Licensed under the Apache License, Version 2.0 (the "License");
193 - you may not use this file except in compliance with the License.
194 - You may obtain a copy of the License at
195 -
196 - http://www.apache.org/licenses/LICENSE-2.0
197 -
198 - Unless required by applicable law or agreed to in writing, software
199 - distributed under the License is distributed on an "AS IS" BASIS,
200 - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 - See the License for the specific language governing permissions and
202 - limitations under the License.
contrib/persistent-https/Makefile deleted
-43
@@ -1,43 +0,0 @@
1 -# Copyright 2012 Google Inc. All Rights Reserved.
2 -#
3 -# Licensed under the Apache License, Version 2.0 (the "License");
4 -# you may not use this file except in compliance with the License.
5 -# You may obtain a copy of the License at
6 -#
7 -# http://www.apache.org/licenses/LICENSE-2.0
8 -#
9 -# Unless required by applicable law or agreed to in writing, software
10 -# distributed under the License is distributed on an "AS IS" BASIS,
11 -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -# See the License for the specific language governing permissions and
13 -# limitations under the License.
14 -
15 -# The default target of this Makefile is...
16 -all::
17 -
18 -BUILD_LABEL=$(shell cut -d" " -f3 ../../GIT-VERSION-FILE)
19 -TAR_OUT=$(shell go env GOOS)_$(shell go env GOARCH).tar.gz
20 -
21 -all:: git-remote-persistent-https git-remote-persistent-https--proxy \
22 - git-remote-persistent-http
23 -
24 -git-remote-persistent-https--proxy: git-remote-persistent-https
25 - ln -f -s git-remote-persistent-https git-remote-persistent-https--proxy
26 -
27 -git-remote-persistent-http: git-remote-persistent-https
28 - ln -f -s git-remote-persistent-https git-remote-persistent-http
29 -
30 -git-remote-persistent-https:
31 - case $$(go version) in \
32 - "go version go"1.[0-5].*) EQ=" " ;; *) EQ="=" ;; esac && \
33 - go build -o git-remote-persistent-https \
34 - -ldflags "-X main._BUILD_EMBED_LABEL$${EQ}$(BUILD_LABEL)"
35 -
36 -clean:
37 - rm -f git-remote-persistent-http* *.tar.gz
38 -
39 -tar: clean all
40 - @chmod 555 git-remote-persistent-https
41 - @tar -czf $(TAR_OUT) git-remote-persistent-http* README LICENSE
42 - @echo
43 - @echo "Created $(TAR_OUT)"
contrib/persistent-https/README deleted
-72
@@ -1,72 +0,0 @@
1 -git-remote-persistent-https
2 -
3 -The git-remote-persistent-https binary speeds up SSL operations
4 -by running a daemon job (git-remote-persistent-https--proxy) that
5 -keeps a connection open to a server.
6 -
7 -
8 -PRE-BUILT BINARIES
9 -
10 -Darwin amd64:
11 -https://commondatastorage.googleapis.com/git-remote-persistent-https/darwin_amd64.tar.gz
12 -
13 -Linux amd64:
14 -https://commondatastorage.googleapis.com/git-remote-persistent-https/linux_amd64.tar.gz
15 -
16 -
17 -INSTALLING
18 -
19 -Move all of the git-remote-persistent-http* binaries to a directory
20 -in PATH.
21 -
22 -
23 -USAGE
24 -
25 -HTTPS requests can be delegated to the proxy by using the
26 -"persistent-https" scheme, e.g.
27 -
28 -git clone persistent-https://kernel.googlesource.com/pub/scm/git/git
29 -
30 -Likewise, .gitconfig can be updated as follows to rewrite https urls
31 -to use persistent-https:
32 -
33 -[url "persistent-https"]
34 - insteadof = https
35 -[url "persistent-http"]
36 - insteadof = http
37 -
38 -You may also want to allow the use of the persistent-https helper for
39 -submodule URLs (since any https URLs pointing to submodules will be
40 -rewritten, and Git's out-of-the-box defaults forbid submodules from
41 -using unknown remote helpers):
42 -
43 -[protocol "persistent-https"]
44 - allow = always
45 -[protocol "persistent-http"]
46 - allow = always
47 -
48 -
49 -#####################################################################
50 -# BUILDING FROM SOURCE
51 -#####################################################################
52 -
53 -LOCATION
54 -
55 -The source is available in the contrib/persistent-https directory of
56 -the Git source repository. The Git source repository is available at
57 -git://git.kernel.org/pub/scm/git/git.git/
58 -https://kernel.googlesource.com/pub/scm/git/git
59 -
60 -
61 -PREREQUISITES
62 -
63 -The code is written in Go (http://golang.org/) and the Go compiler is
64 -required. Currently, the compiler must be built and installed from tip
65 -of source, in order to include a fix in the reverse http proxy:
66 -http://code.google.com/p/go/source/detail?r=a615b796570a2cd8591884767a7d67ede74f6648
67 -
68 -
69 -BUILDING
70 -
71 -Run "make" to build the binaries. See the section on
72 -INSTALLING above.
contrib/persistent-https/client.go deleted
-189
@@ -1,189 +0,0 @@
1 -// Copyright 2012 Google Inc. All Rights Reserved.
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package main
16 -
17 -import (
18 - "bufio"
19 - "errors"
20 - "fmt"
21 - "net"
22 - "net/url"
23 - "os"
24 - "os/exec"
25 - "strings"
26 - "syscall"
27 - "time"
28 -)
29 -
30 -type Client struct {
31 - ProxyBin string
32 - Args []string
33 -
34 - insecure bool
35 -}
36 -
37 -func (c *Client) Run() error {
38 - if err := c.resolveArgs(); err != nil {
39 - return fmt.Errorf("resolveArgs() got error: %v", err)
40 - }
41 -
42 - // Connect to the proxy.
43 - uconn, hconn, addr, err := c.connect()
44 - if err != nil {
45 - return fmt.Errorf("connect() got error: %v", err)
46 - }
47 - // Keep the unix socket connection open for the duration of the request.
48 - defer uconn.Close()
49 - // Keep a connection to the HTTP server open, so no other user can
50 - // bind on the same address so long as the process is running.
51 - defer hconn.Close()
52 -
53 - // Start the git-remote-http subprocess.
54 - cargs := []string{"-c", fmt.Sprintf("http.proxy=%v", addr), "remote-http"}
55 - cargs = append(cargs, c.Args...)
56 - cmd := exec.Command("git", cargs...)
57 -
58 - for _, v := range os.Environ() {
59 - if !strings.HasPrefix(v, "GIT_PERSISTENT_HTTPS_SECURE=") {
60 - cmd.Env = append(cmd.Env, v)
61 - }
62 - }
63 - // Set the GIT_PERSISTENT_HTTPS_SECURE environment variable when
64 - // the proxy is using a SSL connection. This allows credential helpers
65 - // to identify secure proxy connections, despite being passed an HTTP
66 - // scheme.
67 - if !c.insecure {
68 - cmd.Env = append(cmd.Env, "GIT_PERSISTENT_HTTPS_SECURE=1")
69 - }
70 -
71 - cmd.Stdin = os.Stdin
72 - cmd.Stdout = os.Stdout
73 - cmd.Stderr = os.Stderr
74 - if err := cmd.Run(); err != nil {
75 - if eerr, ok := err.(*exec.ExitError); ok {
76 - if stat, ok := eerr.ProcessState.Sys().(syscall.WaitStatus); ok && stat.ExitStatus() != 0 {
77 - os.Exit(stat.ExitStatus())
78 - }
79 - }
80 - return fmt.Errorf("git-remote-http subprocess got error: %v", err)
81 - }
82 - return nil
83 -}
84 -
85 -func (c *Client) connect() (uconn net.Conn, hconn net.Conn, addr string, err error) {
86 - uconn, err = DefaultSocket.Dial()
87 - if err != nil {
88 - if e, ok := err.(*net.OpError); ok && (os.IsNotExist(e.Err) || e.Err == syscall.ECONNREFUSED) {
89 - if err = c.startProxy(); err == nil {
90 - uconn, err = DefaultSocket.Dial()
91 - }
92 - }
93 - if err != nil {
94 - return
95 - }
96 - }
97 -
98 - if addr, err = c.readAddr(uconn); err != nil {
99 - return
100 - }
101 -
102 - // Open a tcp connection to the proxy.
103 - if hconn, err = net.Dial("tcp", addr); err != nil {
104 - return
105 - }
106 -
107 - // Verify the address hasn't changed ownership.
108 - var addr2 string
109 - if addr2, err = c.readAddr(uconn); err != nil {
110 - return
111 - } else if addr != addr2 {
112 - err = fmt.Errorf("address changed after connect. got %q, want %q", addr2, addr)
113 - return
114 - }
115 - return
116 -}
117 -
118 -func (c *Client) readAddr(conn net.Conn) (string, error) {
119 - conn.SetDeadline(time.Now().Add(5 * time.Second))
120 - data := make([]byte, 100)
121 - n, err := conn.Read(data)
122 - if err != nil {
123 - return "", fmt.Errorf("error reading unix socket: %v", err)
124 - } else if n == 0 {
125 - return "", errors.New("empty data response")
126 - }
127 - conn.Write([]byte{1}) // Ack
128 -
129 - var addr string
130 - if addrs := strings.Split(string(data[:n]), "\n"); len(addrs) != 2 {
131 - return "", fmt.Errorf("got %q, wanted 2 addresses", data[:n])
132 - } else if c.insecure {
133 - addr = addrs[1]
134 - } else {
135 - addr = addrs[0]
136 - }
137 - return addr, nil
138 -}
139 -
140 -func (c *Client) startProxy() error {
141 - cmd := exec.Command(c.ProxyBin)
142 - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
143 - stdout, err := cmd.StdoutPipe()
144 - if err != nil {
145 - return err
146 - }
147 - defer stdout.Close()
148 - if err := cmd.Start(); err != nil {
149 - return err
150 - }
151 - result := make(chan error)
152 - go func() {
153 - bytes, _, err := bufio.NewReader(stdout).ReadLine()
154 - if line := string(bytes); err == nil && line != "OK" {
155 - err = fmt.Errorf("proxy returned %q, want \"OK\"", line)
156 - }
157 - result <- err
158 - }()
159 - select {
160 - case err := <-result:
161 - return err
162 - case <-time.After(5 * time.Second):
163 - return errors.New("timeout waiting for proxy to start")
164 - }
165 - panic("not reachable")
166 -}
167 -
168 -func (c *Client) resolveArgs() error {
169 - if nargs := len(c.Args); nargs == 0 {
170 - return errors.New("remote needed")
171 - } else if nargs > 2 {
172 - return fmt.Errorf("want at most 2 args, got %v", c.Args)
173 - }
174 -
175 - // Rewrite the url scheme to be http.
176 - idx := len(c.Args) - 1
177 - rawurl := c.Args[idx]
178 - rurl, err := url.Parse(rawurl)
179 - if err != nil {
180 - return fmt.Errorf("invalid remote: %v", err)
181 - }
182 - c.insecure = rurl.Scheme == "persistent-http"
183 - rurl.Scheme = "http"
184 - c.Args[idx] = rurl.String()
185 - if idx != 0 && c.Args[0] == rawurl {
186 - c.Args[0] = c.Args[idx]
187 - }
188 - return nil
189 -}
contrib/persistent-https/main.go deleted
-82
@@ -1,82 +0,0 @@
1 -// Copyright 2012 Google Inc. All Rights Reserved.
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -// The git-remote-persistent-https binary speeds up SSL operations by running
16 -// a daemon job that keeps a connection open to a Git server. This ensures the
17 -// git-remote-persistent-https--proxy is running and delegating execution
18 -// to the git-remote-http binary with the http_proxy set to the daemon job.
19 -// A unix socket is used to authenticate the proxy and discover the
20 -// HTTP address. Note, both the client and proxy are included in the same
21 -// binary.
22 -package main
23 -
24 -import (
25 - "flag"
26 - "fmt"
27 - "log"
28 - "os"
29 - "strings"
30 - "time"
31 -)
32 -
33 -var (
34 - forceProxy = flag.Bool("proxy", false, "Whether to start the binary in proxy mode")
35 - proxyBin = flag.String("proxy_bin", "git-remote-persistent-https--proxy", "Path to the proxy binary")
36 - printLabel = flag.Bool("print_label", false, "Prints the build label for the binary")
37 -
38 - // Variable that should be defined through the -X linker flag.
39 - _BUILD_EMBED_LABEL string
40 -)
41 -
42 -const (
43 - defaultMaxIdleDuration = 24 * time.Hour
44 - defaultPollUpdateInterval = 15 * time.Minute
45 -)
46 -
47 -func main() {
48 - flag.Parse()
49 - if *printLabel {
50 - // Short circuit execution to print the build label
51 - fmt.Println(buildLabel())
52 - return
53 - }
54 -
55 - var err error
56 - if *forceProxy || strings.HasSuffix(os.Args[0], "--proxy") {
57 - log.SetPrefix("git-remote-persistent-https--proxy: ")
58 - proxy := &Proxy{
59 - BuildLabel: buildLabel(),
60 - MaxIdleDuration: defaultMaxIdleDuration,
61 - PollUpdateInterval: defaultPollUpdateInterval,
62 - }
63 - err = proxy.Run()
64 - } else {
65 - log.SetPrefix("git-remote-persistent-https: ")
66 - client := &Client{
67 - ProxyBin: *proxyBin,
68 - Args: flag.Args(),
69 - }
70 - err = client.Run()
71 - }
72 - if err != nil {
73 - log.Fatalln(err)
74 - }
75 -}
76 -
77 -func buildLabel() string {
78 - if _BUILD_EMBED_LABEL == "" {
79 - log.Println(`unlabeled build; build with "make" to label`)
80 - }
81 - return _BUILD_EMBED_LABEL
82 -}
contrib/persistent-https/proxy.go deleted
-190
@@ -1,190 +0,0 @@
1 -// Copyright 2012 Google Inc. All Rights Reserved.
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package main
16 -
17 -import (
18 - "fmt"
19 - "log"
20 - "net"
21 - "net/http"
22 - "net/http/httputil"
23 - "os"
24 - "os/exec"
25 - "os/signal"
26 - "sync"
27 - "syscall"
28 - "time"
29 -)
30 -
31 -type Proxy struct {
32 - BuildLabel string
33 - MaxIdleDuration time.Duration
34 - PollUpdateInterval time.Duration
35 -
36 - ul net.Listener
37 - httpAddr string
38 - httpsAddr string
39 -}
40 -
41 -func (p *Proxy) Run() error {
42 - hl, err := net.Listen("tcp", "127.0.0.1:0")
43 - if err != nil {
44 - return fmt.Errorf("http listen failed: %v", err)
45 - }
46 - defer hl.Close()
47 -
48 - hsl, err := net.Listen("tcp", "127.0.0.1:0")
49 - if err != nil {
50 - return fmt.Errorf("https listen failed: %v", err)
51 - }
52 - defer hsl.Close()
53 -
54 - p.ul, err = DefaultSocket.Listen()
55 - if err != nil {
56 - c, derr := DefaultSocket.Dial()
57 - if derr == nil {
58 - c.Close()
59 - fmt.Println("OK\nA proxy is already running... exiting")
60 - return nil
61 - } else if e, ok := derr.(*net.OpError); ok && e.Err == syscall.ECONNREFUSED {
62 - // Nothing is listening on the socket, unlink it and try again.
63 - syscall.Unlink(DefaultSocket.Path())
64 - p.ul, err = DefaultSocket.Listen()
65 - }
66 - if err != nil {
67 - return fmt.Errorf("unix listen failed on %v: %v", DefaultSocket.Path(), err)
68 - }
69 - }
70 - defer p.ul.Close()
71 - go p.closeOnSignal()
72 - go p.closeOnUpdate()
73 -
74 - p.httpAddr = hl.Addr().String()
75 - p.httpsAddr = hsl.Addr().String()
76 - fmt.Printf("OK\nListening on unix socket=%v http=%v https=%v\n",
77 - p.ul.Addr(), p.httpAddr, p.httpsAddr)
78 -
79 - result := make(chan error, 2)
80 - go p.serveUnix(result)
81 - go func() {
82 - result <- http.Serve(hl, &httputil.ReverseProxy{
83 - FlushInterval: 500 * time.Millisecond,
84 - Director: func(r *http.Request) {},
85 - })
86 - }()
87 - go func() {
88 - result <- http.Serve(hsl, &httputil.ReverseProxy{
89 - FlushInterval: 500 * time.Millisecond,
90 - Director: func(r *http.Request) {
91 - r.URL.Scheme = "https"
92 - },
93 - })
94 - }()
95 - return <-result
96 -}
97 -
98 -type socketContext struct {
99 - sync.WaitGroup
100 - mutex sync.Mutex
101 - last time.Time
102 -}
103 -
104 -func (sc *socketContext) Done() {
105 - sc.mutex.Lock()
106 - defer sc.mutex.Unlock()
107 - sc.last = time.Now()
108 - sc.WaitGroup.Done()
109 -}
110 -
111 -func (p *Proxy) serveUnix(result chan<- error) {
112 - sockCtx := &socketContext{}
113 - go p.closeOnIdle(sockCtx)
114 -
115 - var err error
116 - for {
117 - var uconn net.Conn
118 - uconn, err = p.ul.Accept()
119 - if err != nil {
120 - err = fmt.Errorf("accept failed: %v", err)
121 - break
122 - }
123 - sockCtx.Add(1)
124 - go p.handleUnixConn(sockCtx, uconn)
125 - }
126 - sockCtx.Wait()
127 - result <- err
128 -}
129 -
130 -func (p *Proxy) handleUnixConn(sockCtx *socketContext, uconn net.Conn) {
131 - defer sockCtx.Done()
132 - defer uconn.Close()
133 - data := []byte(fmt.Sprintf("%v\n%v", p.httpsAddr, p.httpAddr))
134 - uconn.SetDeadline(time.Now().Add(5 * time.Second))
135 - for i := 0; i < 2; i++ {
136 - if n, err := uconn.Write(data); err != nil {
137 - log.Printf("error sending http addresses: %+v\n", err)
138 - return
139 - } else if n != len(data) {
140 - log.Printf("sent %d data bytes, wanted %d\n", n, len(data))
141 - return
142 - }
143 - if _, err := uconn.Read([]byte{0, 0, 0, 0}); err != nil {
144 - log.Printf("error waiting for Ack: %+v\n", err)
145 - return
146 - }
147 - }
148 - // Wait without a deadline for the client to finish via EOF
149 - uconn.SetDeadline(time.Time{})
150 - uconn.Read([]byte{0, 0, 0, 0})
151 -}
152 -
153 -func (p *Proxy) closeOnIdle(sockCtx *socketContext) {
154 - for d := p.MaxIdleDuration; d > 0; {
155 - time.Sleep(d)
156 - sockCtx.Wait()
157 - sockCtx.mutex.Lock()
158 - if d = sockCtx.last.Add(p.MaxIdleDuration).Sub(time.Now()); d <= 0 {
159 - log.Println("graceful shutdown from idle timeout")
160 - p.ul.Close()
161 - }
162 - sockCtx.mutex.Unlock()
163 - }
164 -}
165 -
166 -func (p *Proxy) closeOnUpdate() {
167 - for {
168 - time.Sleep(p.PollUpdateInterval)
169 - if out, err := exec.Command(os.Args[0], "--print_label").Output(); err != nil {
170 - log.Printf("error polling for updated binary: %v\n", err)
171 - } else if s := string(out[:len(out)-1]); p.BuildLabel != s {
172 - log.Printf("graceful shutdown from updated binary: %q --> %q\n", p.BuildLabel, s)
173 - p.ul.Close()
174 - break
175 - }
176 - }
177 -}
178 -
179 -func (p *Proxy) closeOnSignal() {
180 - ch := make(chan os.Signal, 10)
181 - signal.Notify(ch, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM), os.Signal(syscall.SIGHUP))
182 - sig := <-ch
183 - p.ul.Close()
184 - switch sig {
185 - case os.Signal(syscall.SIGHUP):
186 - log.Printf("graceful shutdown from signal: %v\n", sig)
187 - default:
188 - log.Fatalf("exiting from signal: %v\n", sig)
189 - }
190 -}
contrib/persistent-https/socket.go deleted
-97
@@ -1,97 +0,0 @@
1 -// Copyright 2012 Google Inc. All Rights Reserved.
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package main
16 -
17 -import (
18 - "fmt"
19 - "log"
20 - "net"
21 - "os"
22 - "path/filepath"
23 - "syscall"
24 -)
25 -
26 -// A Socket is a wrapper around a Unix socket that verifies directory
27 -// permissions.
28 -type Socket struct {
29 - Dir string
30 -}
31 -
32 -func defaultDir() string {
33 - sockPath := ".git-credential-cache"
34 - if home := os.Getenv("HOME"); home != "" {
35 - return filepath.Join(home, sockPath)
36 - }
37 - log.Printf("socket: cannot find HOME path. using relative directory %q for socket", sockPath)
38 - return sockPath
39 -}
40 -
41 -// DefaultSocket is a Socket in the $HOME/.git-credential-cache directory.
42 -var DefaultSocket = Socket{Dir: defaultDir()}
43 -
44 -// Listen announces the local network address of the unix socket. The
45 -// permissions on the socket directory are verified before attempting
46 -// the actual listen.
47 -func (s Socket) Listen() (net.Listener, error) {
48 - network, addr := "unix", s.Path()
49 - if err := s.mkdir(); err != nil {
50 - return nil, &net.OpError{Op: "listen", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
51 - }
52 - return net.Listen(network, addr)
53 -}
54 -
55 -// Dial connects to the unix socket. The permissions on the socket directory
56 -// are verified before attempting the actual dial.
57 -func (s Socket) Dial() (net.Conn, error) {
58 - network, addr := "unix", s.Path()
59 - if err := s.checkPermissions(); err != nil {
60 - return nil, &net.OpError{Op: "dial", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
61 - }
62 - return net.Dial(network, addr)
63 -}
64 -
65 -// Path returns the fully specified file name of the unix socket.
66 -func (s Socket) Path() string {
67 - return filepath.Join(s.Dir, "persistent-https-proxy-socket")
68 -}
69 -
70 -func (s Socket) mkdir() error {
71 - if err := s.checkPermissions(); err == nil {
72 - return nil
73 - } else if !os.IsNotExist(err) {
74 - return err
75 - }
76 - if err := os.MkdirAll(s.Dir, 0700); err != nil {
77 - return err
78 - }
79 - return s.checkPermissions()
80 -}
81 -
82 -func (s Socket) checkPermissions() error {
83 - fi, err := os.Stat(s.Dir)
84 - if err != nil {
85 - return err
86 - }
87 - if !fi.IsDir() {
88 - return fmt.Errorf("socket: got file, want directory for %q", s.Dir)
89 - }
90 - if fi.Mode().Perm() != 0700 {
91 - return fmt.Errorf("socket: got perm %o, want 700 for %q", fi.Mode().Perm(), s.Dir)
92 - }
93 - if st := fi.Sys().(*syscall.Stat_t); int(st.Uid) != os.Getuid() {
94 - return fmt.Errorf("socket: got uid %d, want %d for %q", st.Uid, os.Getuid(), s.Dir)
95 - }
96 - return nil
97 -}