mirror of
https://github.com/axllent/mailpit.git
synced 2026-06-28 06:56:06 +00:00
Chore: Remove gorilla/mux dependency and replace with stdlib routing
This commit is contained in:
1
go.mod
1
go.mod
@@ -9,7 +9,6 @@ require (
|
||||
github.com/axllent/semver v1.0.0
|
||||
github.com/goccy/go-yaml v1.19.2
|
||||
github.com/gomarkdown/markdown v0.0.0-20260412113850-134a5b2cce7f
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/jhillyerd/enmime/v2 v2.3.0
|
||||
github.com/klauspost/compress v1.18.5
|
||||
|
||||
2
go.sum
2
go.sum
@@ -47,8 +47,6 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"net/url"
|
||||
|
||||
"github.com/axllent/mailpit/internal/storage"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// GetMessage (method: GET) returns the Message as JSON
|
||||
@@ -32,9 +31,7 @@ func GetMessage(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
@@ -78,9 +75,7 @@ func GetHeaders(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
@@ -133,10 +128,8 @@ func DownloadAttachment(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
partID := vars["partID"]
|
||||
id := r.PathValue("id")
|
||||
partID := r.PathValue("partID")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
@@ -183,9 +176,7 @@ func DownloadRaw(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
dl := r.FormValue("dl")
|
||||
|
||||
if id == "latest" {
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/axllent/mailpit/internal/linkcheck"
|
||||
"github.com/axllent/mailpit/internal/spamassassin"
|
||||
"github.com/axllent/mailpit/internal/storage"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/jhillyerd/enmime/v2"
|
||||
)
|
||||
|
||||
@@ -35,8 +34,7 @@ func HTMLCheck(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
@@ -105,8 +103,7 @@ func LinkCheck(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
@@ -158,8 +155,7 @@ func SpamAssassinCheck(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/axllent/mailpit/internal/smtpd"
|
||||
"github.com/axllent/mailpit/internal/storage"
|
||||
"github.com/axllent/mailpit/internal/tools"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/lithammer/shortuuid/v4"
|
||||
)
|
||||
|
||||
@@ -45,9 +44,7 @@ func ReleaseMessage(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
id := r.PathValue("id")
|
||||
|
||||
msg, err := storage.GetMessageRaw(id)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/axllent/mailpit/internal/storage"
|
||||
"github.com/axllent/mailpit/server/websockets"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// GetAllTags (method: GET) will get all tags currently in use
|
||||
@@ -97,9 +96,7 @@ func RenameTag(w http.ResponseWriter, r *http.Request) {
|
||||
// 200: OKResponse
|
||||
// 400: ErrorResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
tag := vars["tag"]
|
||||
tag := r.PathValue("tag")
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
|
||||
@@ -141,9 +138,7 @@ func DeleteTag(w http.ResponseWriter, r *http.Request) {
|
||||
// 200: OKResponse
|
||||
// 400: ErrorResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
tag := vars["tag"]
|
||||
tag := r.PathValue("tag")
|
||||
|
||||
if err := storage.DeleteTag(tag); err != nil {
|
||||
httpError(w, err.Error())
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/axllent/mailpit/internal/logger"
|
||||
"github.com/axllent/mailpit/internal/storage"
|
||||
"github.com/axllent/mailpit/internal/tools"
|
||||
"github.com/gorilla/mux"
|
||||
"golang.org/x/net/html"
|
||||
"golang.org/x/net/html/atom"
|
||||
)
|
||||
@@ -38,9 +37,8 @@ func GetMessageHTML(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
path := strings.TrimPrefix(r.URL.Path, config.Webroot+"view/")
|
||||
id := strings.TrimSuffix(path, ".html")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
@@ -123,9 +121,8 @@ func GetMessageText(w http.ResponseWriter, r *http.Request) {
|
||||
// 400: ErrorResponse
|
||||
// 404: NotFoundResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
path := strings.TrimPrefix(r.URL.Path, config.Webroot+"view/")
|
||||
id := strings.TrimSuffix(path, ".txt")
|
||||
|
||||
if id == "latest" {
|
||||
var err error
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
"github.com/axllent/mailpit/internal/logger"
|
||||
"github.com/axllent/mailpit/internal/storage"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/jhillyerd/enmime/v2"
|
||||
"github.com/kovidgoyal/imaging"
|
||||
)
|
||||
@@ -42,10 +41,8 @@ func Thumbnail(w http.ResponseWriter, r *http.Request) {
|
||||
// 200: BinaryResponse
|
||||
// 400: ErrorResponse
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
id := vars["id"]
|
||||
partID := vars["partID"]
|
||||
id := r.PathValue("id")
|
||||
partID := r.PathValue("partID")
|
||||
|
||||
a, err := storage.GetAttachmentPart(id, partID)
|
||||
if err != nil {
|
||||
|
||||
118
server/server.go
118
server/server.go
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/axllent/mailpit/server/apiv1"
|
||||
"github.com/axllent/mailpit/server/handlers"
|
||||
"github.com/axllent/mailpit/server/websockets"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/lithammer/shortuuid/v4"
|
||||
)
|
||||
|
||||
@@ -64,37 +63,43 @@ func Listen() {
|
||||
r := apiRoutes()
|
||||
|
||||
// kubernetes probes
|
||||
r.HandleFunc(config.Webroot+"livez", handlers.HealthzHandler)
|
||||
r.HandleFunc(config.Webroot+"readyz", handlers.ReadyzHandler(isReady))
|
||||
r.HandleFunc("GET "+config.Webroot+"livez", handlers.HealthzHandler)
|
||||
r.HandleFunc("GET "+config.Webroot+"readyz", handlers.ReadyzHandler(isReady))
|
||||
|
||||
// proxy handler for screenshots
|
||||
r.HandleFunc(config.Webroot+"proxy", middleWareFunc(handlers.ProxyHandler)).Methods("GET")
|
||||
r.HandleFunc("GET "+config.Webroot+"proxy", middleWareFunc(handlers.ProxyHandler))
|
||||
|
||||
// virtual filesystem for /dist/ & some individual files
|
||||
r.PathPrefix(config.Webroot + "dist/").Handler(middleWareFunc(embedController))
|
||||
r.PathPrefix(config.Webroot + "api/").Handler(middleWareFunc(embedController))
|
||||
r.Path(config.Webroot + "favicon.ico").Handler(middleWareFunc(embedController))
|
||||
r.Path(config.Webroot + "favicon.svg").Handler(middleWareFunc(embedController))
|
||||
r.Path(config.Webroot + "mailpit.svg").Handler(middleWareFunc(embedController))
|
||||
r.Path(config.Webroot + "notification.png").Handler(middleWareFunc(embedController))
|
||||
r.Handle("GET "+config.Webroot+"dist/", middleWareFunc(embedController))
|
||||
r.Handle("GET "+config.Webroot+"api/", middleWareFunc(embedController))
|
||||
r.Handle("GET "+config.Webroot+"favicon.ico", middleWareFunc(embedController))
|
||||
r.Handle("GET "+config.Webroot+"favicon.svg", middleWareFunc(embedController))
|
||||
r.Handle("GET "+config.Webroot+"mailpit.svg", middleWareFunc(embedController))
|
||||
r.Handle("GET "+config.Webroot+"notification.png", middleWareFunc(embedController))
|
||||
|
||||
// redirect to webroot if no trailing slash
|
||||
if config.Webroot != "/" {
|
||||
redirect := strings.TrimRight(config.Webroot, "/")
|
||||
r.HandleFunc(redirect, middleWareFunc(addSlashToWebroot)).Methods("GET")
|
||||
r.HandleFunc("GET "+redirect, middleWareFunc(addSlashToWebroot))
|
||||
}
|
||||
|
||||
// UI shortcut
|
||||
r.HandleFunc(config.Webroot+"view/latest", middleWareFunc(handlers.RedirectToLatestMessage)).Methods("GET")
|
||||
r.HandleFunc("GET "+config.Webroot+"view/latest", middleWareFunc(handlers.RedirectToLatestMessage))
|
||||
|
||||
// frontend testing
|
||||
r.HandleFunc(config.Webroot+"view/{id}.html", middleWareFunc(apiv1.GetMessageHTML)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"view/{id}.txt", middleWareFunc(apiv1.GetMessageText)).Methods("GET")
|
||||
// frontend testing + web UI via virtual index.html
|
||||
// Go's ServeMux wildcards must span a full path segment so {id}.html is invalid;
|
||||
// viewHandler dispatches on the path suffix instead.
|
||||
r.HandleFunc("GET "+config.Webroot+"view/", middleWareFunc(viewHandler))
|
||||
|
||||
// web UI via virtual index.html
|
||||
r.PathPrefix(config.Webroot + "view/").Handler(middleWareFunc(index)).Methods("GET")
|
||||
r.Path(config.Webroot + "search").Handler(middleWareFunc(index)).Methods("GET")
|
||||
r.Path(config.Webroot).Handler(middleWareFunc(index)).Methods("GET")
|
||||
r.Handle("GET "+config.Webroot+"search", middleWareFunc(index))
|
||||
// Exact-match the webroot; stdlib "/" is always a subtree so we guard inside.
|
||||
r.HandleFunc("GET "+config.Webroot, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != config.Webroot {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
middleWareFunc(index)(w, r)
|
||||
})
|
||||
|
||||
if auth.UICredentials != nil {
|
||||
logger.Log().Info("[http] enabling basic authentication")
|
||||
@@ -165,51 +170,51 @@ func Listen() {
|
||||
}
|
||||
}
|
||||
|
||||
func apiRoutes() *mux.Router {
|
||||
r := mux.NewRouter()
|
||||
func apiRoutes() *http.ServeMux {
|
||||
r := http.NewServeMux()
|
||||
|
||||
// API V1
|
||||
r.HandleFunc(config.Webroot+"api/v1/messages", middleWareFunc(apiv1.GetMessages)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/messages", middleWareFunc(apiv1.SetReadStatus)).Methods("PUT")
|
||||
r.HandleFunc(config.Webroot+"api/v1/messages", middleWareFunc(apiv1.DeleteMessages)).Methods("DELETE")
|
||||
r.HandleFunc(config.Webroot+"api/v1/search", middleWareFunc(apiv1.Search)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/search", middleWareFunc(apiv1.DeleteSearch)).Methods("DELETE")
|
||||
r.HandleFunc(config.Webroot+"api/v1/send", sendAPIAuthMiddleware(apiv1.SendMessageHandler)).Methods("POST")
|
||||
r.HandleFunc(config.Webroot+"api/v1/tags", middleWareFunc(apiv1.GetAllTags)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/tags", middleWareFunc(apiv1.SetMessageTags)).Methods("PUT")
|
||||
r.HandleFunc(config.Webroot+"api/v1/tags/{tag}", middleWareFunc(apiv1.RenameTag)).Methods("PUT")
|
||||
r.HandleFunc(config.Webroot+"api/v1/tags/{tag}", middleWareFunc(apiv1.DeleteTag)).Methods("DELETE")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/part/{partID}", middleWareFunc(apiv1.DownloadAttachment)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/part/{partID}/thumb", middleWareFunc(apiv1.Thumbnail)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/headers", middleWareFunc(apiv1.GetHeaders)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/raw", middleWareFunc(apiv1.DownloadRaw)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/release", middleWareFunc(apiv1.ReleaseMessage)).Methods("POST")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/html-check", middleWareFunc(apiv1.HTMLCheck)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/link-check", middleWareFunc(apiv1.LinkCheck)).Methods("GET")
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/messages", middleWareFunc(apiv1.GetMessages))
|
||||
r.HandleFunc("PUT "+config.Webroot+"api/v1/messages", middleWareFunc(apiv1.SetReadStatus))
|
||||
r.HandleFunc("DELETE "+config.Webroot+"api/v1/messages", middleWareFunc(apiv1.DeleteMessages))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/search", middleWareFunc(apiv1.Search))
|
||||
r.HandleFunc("DELETE "+config.Webroot+"api/v1/search", middleWareFunc(apiv1.DeleteSearch))
|
||||
r.HandleFunc("POST "+config.Webroot+"api/v1/send", sendAPIAuthMiddleware(apiv1.SendMessageHandler))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/tags", middleWareFunc(apiv1.GetAllTags))
|
||||
r.HandleFunc("PUT "+config.Webroot+"api/v1/tags", middleWareFunc(apiv1.SetMessageTags))
|
||||
r.HandleFunc("PUT "+config.Webroot+"api/v1/tags/{tag}", middleWareFunc(apiv1.RenameTag))
|
||||
r.HandleFunc("DELETE "+config.Webroot+"api/v1/tags/{tag}", middleWareFunc(apiv1.DeleteTag))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/part/{partID}", middleWareFunc(apiv1.DownloadAttachment))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/part/{partID}/thumb", middleWareFunc(apiv1.Thumbnail))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/headers", middleWareFunc(apiv1.GetHeaders))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/raw", middleWareFunc(apiv1.DownloadRaw))
|
||||
r.HandleFunc("POST "+config.Webroot+"api/v1/message/{id}/release", middleWareFunc(apiv1.ReleaseMessage))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/html-check", middleWareFunc(apiv1.HTMLCheck))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/link-check", middleWareFunc(apiv1.LinkCheck))
|
||||
if config.EnableSpamAssassin != "" {
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/sa-check", middleWareFunc(apiv1.SpamAssassinCheck)).Methods("GET")
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}/sa-check", middleWareFunc(apiv1.SpamAssassinCheck))
|
||||
}
|
||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}", middleWareFunc(apiv1.GetMessage)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/info", middleWareFunc(apiv1.AppInfo)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/webui", middleWareFunc(apiv1.WebUIConfig)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/swagger.json", middleWareFunc(swaggerBasePath)).Methods("GET")
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/message/{id}", middleWareFunc(apiv1.GetMessage))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/info", middleWareFunc(apiv1.AppInfo))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/webui", middleWareFunc(apiv1.WebUIConfig))
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/swagger.json", middleWareFunc(swaggerBasePath))
|
||||
|
||||
// Chaos
|
||||
r.HandleFunc(config.Webroot+"api/v1/chaos", middleWareFunc(apiv1.GetChaos)).Methods("GET")
|
||||
r.HandleFunc(config.Webroot+"api/v1/chaos", middleWareFunc(apiv1.SetChaos)).Methods("PUT")
|
||||
r.HandleFunc("GET "+config.Webroot+"api/v1/chaos", middleWareFunc(apiv1.GetChaos))
|
||||
r.HandleFunc("PUT "+config.Webroot+"api/v1/chaos", middleWareFunc(apiv1.SetChaos))
|
||||
|
||||
// Prometheus metrics (if enabled and using existing server)
|
||||
if prometheus.GetMode() == "integrated" {
|
||||
r.HandleFunc(config.Webroot+"metrics", middleWareFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
r.HandleFunc("GET "+config.Webroot+"metrics", middleWareFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
prometheus.GetHandler().ServeHTTP(w, r)
|
||||
})).Methods("GET")
|
||||
}))
|
||||
}
|
||||
|
||||
// web UI websocket
|
||||
r.HandleFunc(config.Webroot+"api/events", middleWareFunc(apiWebsocket)).Methods("GET")
|
||||
r.HandleFunc("GET "+config.Webroot+"api/events", middleWareFunc(apiWebsocket))
|
||||
|
||||
// return blank 200 response for OPTIONS requests for CORS
|
||||
r.PathPrefix(config.Webroot + "api/v1/").Handler(middleWareFunc(apiv1.GetOptions)).Methods("OPTIONS")
|
||||
r.Handle("OPTIONS "+config.Webroot+"api/v1/", middleWareFunc(apiv1.GetOptions))
|
||||
|
||||
return r
|
||||
}
|
||||
@@ -345,6 +350,21 @@ func addSlashToWebroot(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, config.Webroot, http.StatusFound)
|
||||
}
|
||||
|
||||
// viewHandler routes /view/ requests based on path suffix.
|
||||
// Go's ServeMux requires wildcards to span a full path segment,
|
||||
// so patterns like /view/{id}.html are invalid; we dispatch manually here.
|
||||
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, config.Webroot+"view/")
|
||||
switch {
|
||||
case strings.HasSuffix(path, ".html"):
|
||||
apiv1.GetMessageHTML(w, r)
|
||||
case strings.HasSuffix(path, ".txt"):
|
||||
apiv1.GetMessageText(w, r)
|
||||
default:
|
||||
index(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// Websocket to broadcast changes.
|
||||
// Authentication and CORS are handled by middleWareFunc before this is reached.
|
||||
func apiWebsocket(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user