blob: d618ab677601a79ed11b96c49a04935d92f3339c [file] [log] [blame]
Earl Lee2e463fb2025-04-17 11:22:22 -07001package dockerimg
2
3import (
4 "fmt"
5 "log/slog"
6 "net/http"
7 "net/http/cgi"
8 "os/exec"
9 "strings"
10)
11
12type gitHTTP struct {
13 gitRepoRoot string
14}
15
16func (g *gitHTTP) ServeHTTP(w http.ResponseWriter, r *http.Request) {
17 defer func() {
18 if err := recover(); err != nil {
19 slog.ErrorContext(r.Context(), "gitHTTP.ServeHTTP panic", slog.Any("recovered_err", err))
20
21 // Return an error response to the client
22 http.Error(w, fmt.Sprintf("panic: %v\n", err), http.StatusInternalServerError)
23 }
24 }()
25 if !strings.HasPrefix(r.RemoteAddr, "127.0.0.1:") {
26 slog.InfoContext(r.Context(), "githttp: denied", "remote addr", r.RemoteAddr)
27 http.Error(w, "no", http.StatusUnauthorized)
28 return
29 }
30 gitBin, err := exec.LookPath("git")
31 if err != nil {
32 http.Error(w, "no git: "+err.Error(), http.StatusInternalServerError)
33 return
34 }
35
36 w.Header().Set("Cache-Control", "no-cache")
37 h := &cgi.Handler{
38 Path: gitBin,
39 Args: []string{"http-backend"},
40 Dir: g.gitRepoRoot,
41 Env: []string{
42 "GIT_PROJECT_ROOT=" + g.gitRepoRoot,
43 "PATH_INFO=" + r.URL.Path,
44 "QUERY_STRING=" + r.URL.RawQuery,
45 "REQUEST_METHOD=" + r.Method,
46 "GIT_HTTP_EXPORT_ALL=true",
47 "GIT_HTTP_ALLOW_REPACK=true",
48 "GIT_HTTP_ALLOW_PUSH=true",
49 "GIT_HTTP_VERBOSE=1",
50 },
51 }
52 h.ServeHTTP(w, r)
53}