Example #1
0
func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var g gitService

	if r.URL.Path == status.Path {
		status.HealthyHandler.ServeHTTP(w, r)
		return
	}

	// Look for a matching Git service
	foundService := false
	for _, g = range gitServices {
		if r.Method == g.method && strings.HasSuffix(r.URL.Path, g.suffix) {
			foundService = true
			break
		}
	}
	name := strings.TrimSuffix(strings.TrimPrefix(strings.TrimSuffix(r.URL.Path, g.suffix), "/"), ".git")
	if !foundService || !utils.AppNamePattern.MatchString(name) {
		// The protocol spec in git/Documentation/technical/http-protocol.txt
		// says we must return 403 if no matching service is found.
		http.Error(w, "Forbidden", 403)
		return
	}

	_, password, _ := utils.ParseBasicAuth(r.Header)
	if !hmac.Equal([]byte(password), h.authKey) {
		w.Header().Set("WWW-Authenticate", "Basic")
		http.Error(w, "Authentication required", 401)
		return
	}

	// Lookup app
	app, err := h.controller.GetApp(name)
	if err == controller.ErrNotFound {
		http.Error(w, "unknown app", 404)
		return
	} else if err != nil {
		fail500(w, "getApp", err)
		return
	}

	repoPath, err := prepareRepo(app.ID)
	if err != nil {
		fail500(w, "prepareRepo", err)
		return
	}
	defer os.RemoveAll(repoPath)
	if g.rpc == "git-receive-pack" {
		defer func() {
			if err := uploadRepo(repoPath, app.ID); err != nil {
				logError(w, "uploadRepo", err)
			}
		}()
	}

	g.handleFunc(gitEnv{App: app.ID}, g.rpc, repoPath, w, r)
}
Example #2
0
func (s *statusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if s.k != "" {
		var addr string
		if fwdFor := r.Header.Get("X-Forwarded-For"); fwdFor != "" {
			if v := strings.Split(fwdFor, ", "); len(v) > 0 {
				addr = strings.TrimSpace(v[len(v)-1])
			}
		}
		if addr == "" {
			if clientIP, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
				addr = clientIP
			}
		}

		var authed bool
		if ip := net.ParseIP(addr); ip != nil {
			for _, v := range s.whitelist {
				if v.Contains(ip) {
					authed = true
					break
				}
			}
		}

		if !authed {
			_, password, _ := utils.ParseBasicAuth(r.Header)
			if password == "" {
				password = r.URL.Query().Get("key")
			}
			authed = len(password) == len(s.k) && subtle.ConstantTimeCompare([]byte(password), []byte(s.k)) == 1
		}

		if !authed {
			w.WriteHeader(401)
			return
		}
	}

	s.h.ServeHTTP(w, r)
}