package githttp import ( "compress/flate" "compress/gzip" "fmt" "io" "net/http" "strconv" "strings" "time" ) // requestReader returns an io.ReadCloser // that will decode data if needed, depending on the // "content-encoding" header func requestReader(req *http.Request) (io.ReadCloser, error) { switch req.Header.Get("content-encoding") { case "gzip": return gzip.NewReader(req.Body) case "deflate": return flate.NewReader(req.Body), nil } // If no encoding, use raw body return req.Body, nil } // HTTP parsing utility functions func getServiceType(r *http.Request) string { service_type := r.FormValue("service") if s := strings.HasPrefix(service_type, "git-"); !s { return "" } return strings.Replace(service_type, "git-", "", 1) } // HTTP error response handling functions func renderMethodNotAllowed(w http.ResponseWriter, r *http.Request) { if r.Proto == "HTTP/1.1" { w.WriteHeader(http.StatusMethodNotAllowed) w.Write([]byte("Method Not Allowed")) } else { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Bad Request")) } } func renderNotFound(w http.ResponseWriter) { w.WriteHeader(http.StatusNotFound) w.Write([]byte("Not Found")) } func renderNoAccess(w http.ResponseWriter) { w.WriteHeader(http.StatusForbidden) w.Write([]byte("Forbidden")) } // Packet-line handling function func packetFlush() []byte { return []byte("0000") } func packetWrite(str string) []byte { s := strconv.FormatInt(int64(len(str)+4), 16) if len(s)%4 != 0 { s = strings.Repeat("0", 4-len(s)%4) + s } return []byte(s + str) } // Header writing functions func hdrNocache(w http.ResponseWriter) { w.Header().Set("Expires", "Fri, 01 Jan 1980 00:00:00 GMT") w.Header().Set("Pragma", "no-cache") w.Header().Set("Cache-Control", "no-cache, max-age=0, must-revalidate") } func hdrCacheForever(w http.ResponseWriter) { now := time.Now().Unix() expires := now + 31536000 w.Header().Set("Date", fmt.Sprintf("%d", now)) w.Header().Set("Expires", fmt.Sprintf("%d", expires)) w.Header().Set("Cache-Control", "public, max-age=31536000") }