2024-07-08 17:14:26 +02:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
)
|
|
|
|
|
|
|
|
const RequestType_Push = "push"
|
|
|
|
const RequestType_Repository = "repository"
|
2024-07-09 12:06:24 +02:00
|
|
|
const RequestType_PR = "pull_request"
|
2024-07-10 17:29:36 +02:00
|
|
|
const RequestType_PR_sync = "pull_request_sync"
|
2024-07-08 17:14:26 +02:00
|
|
|
|
|
|
|
type RequestProcessor func(*RequestHandler) error
|
|
|
|
|
|
|
|
type ListenDefinitions struct {
|
|
|
|
GitAuthor, Url string
|
|
|
|
Handlers map[string]RequestProcessor
|
|
|
|
}
|
|
|
|
|
|
|
|
func StartServer(listenDefs ListenDefinitions) {
|
2024-07-09 14:55:12 +02:00
|
|
|
StartServerWithAddress(listenDefs, "[::1]:8000")
|
|
|
|
}
|
|
|
|
|
|
|
|
func StartServerWithAddress(listenDefs ListenDefinitions, addr string) {
|
2024-07-08 17:14:26 +02:00
|
|
|
if listenDefs.Url != url.PathEscape(listenDefs.Url) {
|
|
|
|
log.Fatalf("Invalid Url fragment (%s) to listen on. Aborting", listenDefs.Url)
|
|
|
|
}
|
|
|
|
|
|
|
|
http.HandleFunc("/"+listenDefs.Url, func(res http.ResponseWriter, req *http.Request) {
|
|
|
|
h := CreateRequestHandler(listenDefs.GitAuthor, listenDefs.Url)
|
2024-08-13 16:42:20 +02:00
|
|
|
defer h.Close()
|
2024-07-08 17:14:26 +02:00
|
|
|
|
|
|
|
if len(req.Header.Get("Content-Type")) == 0 ||
|
|
|
|
req.Header["Content-Type"][0] != "application/json" ||
|
|
|
|
req.Method != "POST" {
|
|
|
|
|
|
|
|
h.WriteError()
|
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
hdr := req.Header[GiteaRequestHeader]
|
|
|
|
if len(hdr) != 1 {
|
|
|
|
h.LogError("Unsupported number of %s headers: %d: %#v\n", GiteaRequestHeader, len(hdr), hdr)
|
|
|
|
h.WriteError()
|
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
reqType := hdr[0]
|
|
|
|
|
|
|
|
if handler, ok := listenDefs.Handlers[reqType]; ok {
|
2024-07-09 12:06:24 +02:00
|
|
|
switch reqType {
|
|
|
|
case RequestType_Repository:
|
|
|
|
h.parseRepositoryRequest(req.Body)
|
|
|
|
case RequestType_Push:
|
|
|
|
h.parsePushRequest(req.Body)
|
|
|
|
case RequestType_PR:
|
|
|
|
h.parsePullRequest(req.Body)
|
2024-07-10 17:29:36 +02:00
|
|
|
case RequestType_PR_sync:
|
|
|
|
h.parsePullRequestSync(req.Body)
|
2024-07-09 12:06:24 +02:00
|
|
|
default:
|
|
|
|
h.LogError("Unhandled request type: %s", reqType)
|
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-07-09 23:52:28 +02:00
|
|
|
if h.HasError() {
|
|
|
|
h.LogError("error in parser %s: %v", reqType, h.Error)
|
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-07-08 17:14:26 +02:00
|
|
|
if err := handler(h); err != nil {
|
2024-07-09 12:06:24 +02:00
|
|
|
h.LogError("error in handler for %s: %v", reqType, err)
|
2024-07-08 17:14:26 +02:00
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
h.LogError("Unsupported request type: %s", reqType)
|
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
2024-07-09 12:06:24 +02:00
|
|
|
return
|
2024-07-08 17:14:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if h.HasError() {
|
|
|
|
h.WriteError()
|
|
|
|
res.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
res.Header().Add("Content-Type", "application/json")
|
|
|
|
res.WriteHeader(http.StatusOK)
|
|
|
|
})
|
|
|
|
|
2024-07-09 14:55:12 +02:00
|
|
|
log.Fatal(http.ListenAndServe(addr, nil))
|
2024-07-08 17:14:26 +02:00
|
|
|
}
|