package main import ( "fmt" "io/ioutil" "net/http" "os/user" "path" "strings" "time" ) func ServeGit(out http.ResponseWriter, in *http.Request) { PostHack(in) upath := in.URL.Path if strings.HasPrefix(upath, "/") { upath = "/" + upath } upath = path.Clean(upath) upath = upath[1:] errcheck(GitPull()) tree, err := GitLsTree() errcheck(err) file, fileExists := tree[upath] if in.Method != http.MethodPut { if !fileExists { http.NotFound(out, in) return } if file.Type == "tree" && !strings.HasSuffix(in.URL.Path, "/") { out.Header().Set("Location", path.Base(upath)+"/") out.WriteHeader(http.StatusMovedPermanently) return } } switch in.Method { case http.MethodGet, http.MethodHead: out.Header().Set("Content-Type", "text/html; charset=utf-8") if file.Type == "tree" { errcheck(renderViewTree(out, upath, tree)) } else { errcheck(renderViewBlob(out, upath, file)) } out.WriteHeader(http.StatusOK) case http.MethodPut: username := in.Header.Get("X-Nginx-User") userinfo, err := user.Lookup(username) errcheck(err) msg := in.Header.Get("X-Commit-Message") if msg == "" { msg = fmt.Sprintf("web edit: create/modify %q", upath) } content, err := ioutil.ReadAll(in.Body) errcheck(err) edit := Edit{ UserName: userinfo.Name, UserEmail: username + "@edit.team4272.com", Time: time.Now(), Message: msg + "\n", Files: map[string][]byte{ upath: content, }, } errcheck(GitCommit(edit)) errcheck(GitPush()) errcheck(renderModified(out, upath)) if fileExists { out.WriteHeader(http.StatusOK) } else { out.WriteHeader(http.StatusCreated) } case http.MethodDelete: username := in.Header.Get("X-Nginx-User") userinfo, err := user.Lookup(username) errcheck(err) msg := in.Header.Get("X-Commit-Message") if msg == "" { msg = fmt.Sprintf("web edit: delete %q", upath) } edit := Edit{ UserName: userinfo.Name, UserEmail: username + "@edit.team4272.com", Time: time.Now(), Message: msg + "\n", Files: map[string][]byte{ upath: nil, }, } errcheck(GitCommit(edit)) errcheck(GitPush()) errcheck(renderDeleted(out, upath)) out.WriteHeader(http.StatusOK) case http.MethodOptions: // POST because PostHack out.Header().Set("Allow", "GET, HEAD, PUT, POST, DELETE, OPTIONS") out.WriteHeader(http.StatusOK) default: out.Header().Set("Allow", "GET, HEAD, PUT, POST, DELETE, OPTIONS") out.WriteHeader(http.StatusMethodNotAllowed) } }