133 lines
3.8 KiB
Go
133 lines
3.8 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// ---------------- HTTP routing ----------------
|
|
|
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if strings.HasPrefix(r.URL.Path, "/api/") {
|
|
s.handleAPI(w, r)
|
|
return
|
|
}
|
|
if strings.Contains(r.URL.Path, ".git") {
|
|
s.handleGitHTTP(w, r)
|
|
return
|
|
}
|
|
writeError(w, http.StatusNotFound, "not found")
|
|
}
|
|
|
|
func (s *Server) handleAPI(w http.ResponseWriter, r *http.Request) {
|
|
path := strings.TrimPrefix(r.URL.Path, "/api")
|
|
switch {
|
|
case r.Method == http.MethodPost && path == "/register":
|
|
s.handleRegister(w, r)
|
|
case r.Method == http.MethodPost && path == "/login":
|
|
s.handleLogin(w, r)
|
|
case r.Method == http.MethodPost && path == "/logout":
|
|
s.handleLogout(w, r)
|
|
case r.Method == http.MethodGet && path == "/me":
|
|
s.handleMe(w, r)
|
|
case strings.HasPrefix(path, "/tokens"):
|
|
s.handleTokenRoutes(w, r, strings.TrimPrefix(path, "/tokens"))
|
|
case strings.HasPrefix(path, "/admin"):
|
|
s.handleAdminRoutes(w, r, strings.TrimPrefix(path, "/admin"))
|
|
case r.Method == http.MethodPost && path == "/repos":
|
|
s.handleRepoCreate(w, r)
|
|
case r.Method == http.MethodGet && path == "/repos/search":
|
|
s.handleRepoSearch(w, r)
|
|
case strings.HasPrefix(path, "/repos/"):
|
|
s.handleRepoSubroute(w, r, strings.TrimPrefix(path, "/repos/"))
|
|
default:
|
|
writeError(w, http.StatusNotFound, "not found")
|
|
}
|
|
}
|
|
|
|
func (s *Server) handleRepoSubroute(w http.ResponseWriter, r *http.Request, rest string) {
|
|
parts := strings.Split(rest, "/")
|
|
if len(parts) < 2 {
|
|
writeError(w, http.StatusNotFound, "not found")
|
|
return
|
|
}
|
|
owner, repo := parts[0], parts[1]
|
|
if len(parts) == 2 {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
s.handleRepoGet(w, r, owner, repo)
|
|
case http.MethodPatch:
|
|
s.handleRepoUpdate(w, r, owner, repo)
|
|
case http.MethodDelete:
|
|
s.handleRepoDelete(w, r, owner, repo)
|
|
default:
|
|
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
|
}
|
|
return
|
|
}
|
|
if len(parts) == 3 && parts[2] == "fork" && r.Method == http.MethodPost {
|
|
s.handleRepoFork(w, r, owner, repo)
|
|
return
|
|
}
|
|
if len(parts) == 3 && parts[2] == "branches" && r.Method == http.MethodGet {
|
|
s.handleRepoBranches(w, r, owner, repo)
|
|
return
|
|
}
|
|
if len(parts) == 3 && parts[2] == "tags" && r.Method == http.MethodGet {
|
|
s.handleRepoTags(w, r, owner, repo)
|
|
return
|
|
}
|
|
if len(parts) >= 3 && parts[2] == "collaborators" {
|
|
s.handleCollaborators(w, r, owner, repo, parts[3:])
|
|
return
|
|
}
|
|
if len(parts) >= 3 && parts[2] == "pulls" {
|
|
if len(parts) == 3 {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
s.handlePRList(w, r, owner, repo)
|
|
case http.MethodPost:
|
|
s.handlePRCreate(w, r, owner, repo)
|
|
default:
|
|
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
|
}
|
|
return
|
|
}
|
|
if len(parts) >= 4 {
|
|
n, err := strconv.Atoi(parts[3])
|
|
if err != nil {
|
|
writeError(w, http.StatusBadRequest, "invalid pull request number")
|
|
return
|
|
}
|
|
if len(parts) == 4 && r.Method == http.MethodGet {
|
|
s.handlePRView(w, r, owner, repo, n)
|
|
return
|
|
}
|
|
if len(parts) == 5 && r.Method == http.MethodGet && parts[4] == "diff" {
|
|
s.handlePRDiff(w, r, owner, repo, n)
|
|
return
|
|
}
|
|
if len(parts) == 5 && parts[4] == "comments" {
|
|
if r.Method == http.MethodGet {
|
|
s.handlePRCommentsList(w, r, owner, repo, n)
|
|
} else if r.Method == http.MethodPost {
|
|
s.handlePRCommentCreate(w, r, owner, repo, n)
|
|
} else {
|
|
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
|
}
|
|
return
|
|
}
|
|
if len(parts) == 5 && r.Method == http.MethodPost && parts[4] == "close" {
|
|
s.handlePRClose(w, r, owner, repo, n)
|
|
return
|
|
}
|
|
if len(parts) == 5 && r.Method == http.MethodPost && parts[4] == "merge" {
|
|
s.handlePRMerge(w, r, owner, repo, n)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
writeError(w, http.StatusNotFound, "not found")
|
|
}
|