122 lines
4.7 KiB
Go
122 lines
4.7 KiB
Go
package api
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/args"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/database"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/utils"
|
|
)
|
|
|
|
type RequestContext struct {
|
|
DBConn *sql.DB
|
|
Args *args.Arguments
|
|
|
|
Id string
|
|
Start time.Time
|
|
|
|
User *database.User
|
|
}
|
|
|
|
type Continuation func(*RequestContext, *http.Request, http.ResponseWriter) ContinuationChain
|
|
type ContinuationChain func(Continuation, Continuation) ContinuationChain
|
|
|
|
func LogRequestContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
context.Start = time.Now()
|
|
context.Id = utils.RandomId()
|
|
|
|
log.Println(req.Method, req.URL.Path, req.RemoteAddr, context.Id)
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func LogExecutionTimeContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
end := time.Now()
|
|
|
|
log.Println(context.Id, "took", end.Sub(context.Start))
|
|
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func HealthCheckContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
resp.WriteHeader(200)
|
|
resp.Write([]byte("healthy"))
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func FailurePassingContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(_success Continuation, failure Continuation) ContinuationChain {
|
|
return failure(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func IdContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server {
|
|
mux := http.NewServeMux()
|
|
|
|
fileServer := http.FileServer(http.Dir(argv.StaticPath))
|
|
mux.Handle("/static/", http.StripPrefix("/static/", fileServer))
|
|
|
|
makeRequestContext := func() *RequestContext {
|
|
return &RequestContext{
|
|
DBConn: dbConn,
|
|
Args: argv,
|
|
}
|
|
}
|
|
|
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation("home.html", nil, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /api/health", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(HealthCheckContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /login", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(StartSessionContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /auth", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(InterceptCodeContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /me", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(RefreshSessionContinuation, GoLoginContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /logout", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(LogoutContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /{name}", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
name := r.PathValue("name")
|
|
LogRequestContinuation(requestContext, r, w)(TemplateContinuation(name+".html", nil, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
return &http.Server{
|
|
Addr: ":" + fmt.Sprint(argv.Port),
|
|
Handler: mux,
|
|
}
|
|
}
|