s
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package gitrpc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"simplegit/common"
|
||||
)
|
||||
|
||||
func (s *Server) authorizeRead(w http.ResponseWriter, r *http.Request, repo string) bool {
|
||||
if repo == "" {
|
||||
http.Error(w, "missing repo", http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
if _, status, msg := s.authorize(r, repo, common.PermRead); status != 0 {
|
||||
http.Error(w, msg, status)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Server) serveRaw(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
repoName := q.Get("repo")
|
||||
if !s.authorizeRead(w, r, repoName) {
|
||||
return
|
||||
}
|
||||
ref := q.Get("ref")
|
||||
filePath := q.Get("file")
|
||||
|
||||
repo, err := s.open(r.Context(), repoName)
|
||||
if err != nil {
|
||||
writeHTTPError(w, err)
|
||||
return
|
||||
}
|
||||
content, err := repo.GetRawContent(ref, filePath)
|
||||
if err != nil {
|
||||
http.Error(w, "read file: "+err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
_, _ = io.WriteString(w, content)
|
||||
}
|
||||
|
||||
func (s *Server) servePatch(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
repoName := q.Get("repo")
|
||||
if !s.authorizeRead(w, r, repoName) {
|
||||
return
|
||||
}
|
||||
sha := q.Get("sha")
|
||||
|
||||
repo, err := s.open(r.Context(), repoName)
|
||||
if err != nil {
|
||||
writeHTTPError(w, err)
|
||||
return
|
||||
}
|
||||
patch, err := repo.Patch(sha)
|
||||
if err != nil {
|
||||
http.Error(w, "format-patch: "+err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
_, _ = io.WriteString(w, patch)
|
||||
}
|
||||
|
||||
func (s *Server) serveArchive(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
repoName := q.Get("repo")
|
||||
if !s.authorizeRead(w, r, repoName) {
|
||||
return
|
||||
}
|
||||
ref := q.Get("ref")
|
||||
format := q.Get("format")
|
||||
|
||||
repo, err := s.open(r.Context(), repoName)
|
||||
if err != nil {
|
||||
writeHTTPError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if format == "" {
|
||||
format = "zip"
|
||||
}
|
||||
switch format {
|
||||
case "zip":
|
||||
w.Header().Set("Content-Type", "application/zip")
|
||||
case "tar":
|
||||
w.Header().Set("Content-Type", "application/x-tar")
|
||||
default:
|
||||
http.Error(w, "format must be zip or tar", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo.Archive(ref, format, w); err != nil {
|
||||
|
||||
http.Error(w, "archive: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func writeHTTPError(w http.ResponseWriter, err error) {
|
||||
var re *rpcError
|
||||
if errors.As(err, &re) {
|
||||
switch re.Code {
|
||||
case codeRepoNotFound:
|
||||
http.Error(w, re.Message, http.StatusNotFound)
|
||||
default:
|
||||
http.Error(w, re.Message, http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
Reference in New Issue
Block a user