Files
2026-06-08 15:03:41 -05:00

133 lines
3.7 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
}
s.handleWeb(w, r)
}
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")
}