11 // gitHandler is an http.Handler that invokes git-http-backend (or
12 // whatever backend is configured) via CGI, with appropriate
13 // environment variables in place for git-http-backend or
15 type gitHandler struct {
19 func newGitHandler() http.Handler {
20 const glBypass = "GL_BYPASS_ACCESS_CHECKS"
21 const glHome = "GITOLITE_HTTP_HOME"
23 path := os.Getenv("PATH")
24 if theConfig.GitoliteHome != "" {
26 glHome+"="+theConfig.GitoliteHome,
28 path = path + ":" + theConfig.GitoliteHome + "/bin"
29 } else if home, bypass := os.Getenv(glHome), os.Getenv(glBypass); home != "" || bypass != "" {
30 env = append(env, glHome+"="+home, glBypass+"="+bypass)
31 log.Printf("DEPRECATED: Passing through %s and %s environment variables. Use GitoliteHome configuration instead.", glHome, glBypass)
34 "GIT_PROJECT_ROOT="+theConfig.RepoRoot,
35 "GIT_HTTP_EXPORT_ALL=",
36 "SERVER_ADDR="+theConfig.Listen,
40 Path: theConfig.GitCommand,
41 Dir: theConfig.RepoRoot,
43 Args: []string{"http-backend"},
48 func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
49 remoteHost, remotePort, err := net.SplitHostPort(r.RemoteAddr)
51 log.Printf("Internal error: SplitHostPort(r.RemoteAddr==%q): %s", r.RemoteAddr, err)
52 w.WriteHeader(http.StatusInternalServerError)
56 // Copy the wrapped cgi.Handler, so these request-specific
57 // variables don't leak into the next request.
58 handlerCopy := h.Handler
59 handlerCopy.Env = append(handlerCopy.Env,
60 // In Go1.5 we can skip this, net/http/cgi will do it for us:
61 "REMOTE_HOST="+remoteHost,
62 "REMOTE_ADDR="+remoteHost,
63 "REMOTE_PORT="+remotePort,
64 // Ideally this would be a real username:
65 "REMOTE_USER="+r.RemoteAddr,
67 handlerCopy.ServeHTTP(w, r)