mirror of
https://gitlab.com/ric_harvey/MailHog.git
synced 2025-02-20 01:35:56 +00:00
Clean up routing
This commit is contained in:
parent
fa8e9d1b21
commit
92ff3714ad
4 changed files with 111 additions and 86 deletions
|
@ -5,12 +5,11 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
"net/smtp"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"github.com/ian-kent/MailHog/mailhog/data"
|
||||
"github.com/ian-kent/MailHog/mailhog/config"
|
||||
"github.com/ian-kent/MailHog/mailhog/storage"
|
||||
"github.com/ian-kent/MailHog/mailhog/http/handler"
|
||||
"github.com/ian-kent/MailHog/mailhog/http/router"
|
||||
)
|
||||
|
||||
type APIv1 struct {
|
||||
|
@ -33,18 +32,20 @@ func CreateAPIv1(exitCh chan int, conf *config.Config, server *http.Server) *API
|
|||
server: server,
|
||||
}
|
||||
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/api/v1/messages/?$"), apiv1.messages)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"DELETE"},regexp.MustCompile("^/api/v1/messages/?$"), apiv1.delete_all)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/api/v1/messages/([0-9a-f]+)/?$"), apiv1.message)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"DELETE"},regexp.MustCompile("^/api/v1/messages/([0-9a-f]+)/?$"), apiv1.delete_one)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/api/v1/messages/([0-9a-f]+)/download/?$"), apiv1.download)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/api/v1/messages/([0-9a-f]+)/mime/part/(\\d+)/download/?$"), apiv1.download_part)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"POST"},regexp.MustCompile("^/api/v1/messages/([0-9a-f]+)/release/?$"), apiv1.release_one)
|
||||
r := server.Handler.(*router.Router)
|
||||
|
||||
r.Get("^/api/v1/messages/?$", apiv1.messages)
|
||||
r.Delete("^/api/v1/messages/?$", apiv1.delete_all)
|
||||
r.Get("^/api/v1/messages/([0-9a-f]+)/?$", apiv1.message)
|
||||
r.Delete("^/api/v1/messages/([0-9a-f]+)/?$", apiv1.delete_one)
|
||||
r.Get("^/api/v1/messages/([0-9a-f]+)/download/?$", apiv1.download)
|
||||
r.Get("^/api/v1/messages/([0-9a-f]+)/mime/part/(\\d+)/download/?$", apiv1.download_part)
|
||||
r.Post("^/api/v1/messages/([0-9a-f]+)/release/?$", apiv1.release_one)
|
||||
|
||||
return apiv1
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) messages(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) messages(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
log.Println("[APIv1] GET /api/v1/messages")
|
||||
|
||||
// TODO start, limit
|
||||
|
@ -64,7 +65,7 @@ func (apiv1 *APIv1) messages(w http.ResponseWriter, r *http.Request, route *hand
|
|||
}
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) message(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) message(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
|
||||
match := route.Pattern.FindStringSubmatch(r.URL.Path)
|
||||
id := match[1]
|
||||
|
@ -86,7 +87,7 @@ func (apiv1 *APIv1) message(w http.ResponseWriter, r *http.Request, route *handl
|
|||
}
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) download(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) download(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
match := route.Pattern.FindStringSubmatch(r.URL.Path)
|
||||
id := match[1]
|
||||
log.Printf("[APIv1] GET /api/v1/messages/%s/download\n", id)
|
||||
|
@ -116,7 +117,7 @@ func (apiv1 *APIv1) download(w http.ResponseWriter, r *http.Request, route *hand
|
|||
}
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) download_part(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) download_part(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
match := route.Pattern.FindStringSubmatch(r.URL.Path)
|
||||
id := match[1]
|
||||
part, _ := strconv.Atoi(match[2])
|
||||
|
@ -148,7 +149,7 @@ func (apiv1 *APIv1) download_part(w http.ResponseWriter, r *http.Request, route
|
|||
}
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) delete_all(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) delete_all(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
log.Println("[APIv1] POST /api/v1/messages")
|
||||
|
||||
w.Header().Set("Content-Type", "text/json")
|
||||
|
@ -162,7 +163,7 @@ func (apiv1 *APIv1) delete_all(w http.ResponseWriter, r *http.Request, route *ha
|
|||
}
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) release_one(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) release_one(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
match := route.Pattern.FindStringSubmatch(r.URL.Path)
|
||||
id := match[1]
|
||||
log.Printf("[APIv1] POST /api/v1/messages/%s/release\n", id)
|
||||
|
@ -208,7 +209,7 @@ func (apiv1 *APIv1) release_one(w http.ResponseWriter, r *http.Request, route *h
|
|||
log.Printf("Message released successfully")
|
||||
}
|
||||
|
||||
func (apiv1 *APIv1) delete_one(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func (apiv1 *APIv1) delete_one(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
match := route.Pattern.FindStringSubmatch(r.URL.Path)
|
||||
id := match[1]
|
||||
log.Printf("[APIv1] POST /api/v1/messages/%s/delete\n", id)
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
package handler;
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// http://stackoverflow.com/questions/6564558/wildcards-in-the-pattern-for-http-handlefunc
|
||||
|
||||
type Route struct {
|
||||
Methods map[string]int
|
||||
Pattern *regexp.Regexp
|
||||
Handler HandlerFunc
|
||||
}
|
||||
|
||||
type HandlerFunc func(http.ResponseWriter, *http.Request, *Route)
|
||||
|
||||
//type Handler http.Handler
|
||||
func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, route *Route) {
|
||||
f(w, r, route)
|
||||
}
|
||||
|
||||
type RegexpHandler struct {
|
||||
routes []*Route
|
||||
}
|
||||
|
||||
func (h *RegexpHandler) Handler(methods []string, pattern *regexp.Regexp, handler HandlerFunc) {
|
||||
m := make(map[string]int,0)
|
||||
for _, v := range methods {
|
||||
m[v] = 1
|
||||
}
|
||||
h.routes = append(h.routes, &Route{m, pattern, handler})
|
||||
}
|
||||
|
||||
func (h *RegexpHandler) HandleFunc(methods []string, pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request, *Route)) {
|
||||
m := make(map[string]int,0)
|
||||
for _, v := range methods {
|
||||
m[v] = 1
|
||||
}
|
||||
h.routes = append(h.routes, &Route{m, pattern, HandlerFunc(handler)})
|
||||
}
|
||||
|
||||
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
for _, route := range h.routes {
|
||||
if route.Pattern.MatchString(r.URL.Path) {
|
||||
_, ok := route.Methods[r.Method]
|
||||
if ok {
|
||||
route.Handler.ServeHTTP(w, r, route)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// no pattern matched; send 404 response
|
||||
http.NotFound(w, r)
|
||||
}
|
79
mailhog/http/router/regexp.go
Normal file
79
mailhog/http/router/regexp.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package router;
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// http://stackoverflow.com/questions/6564558/wildcards-in-the-pattern-for-http-handlefunc
|
||||
|
||||
type Route struct {
|
||||
Methods map[string]int
|
||||
Pattern *regexp.Regexp
|
||||
Handler HandlerFunc
|
||||
}
|
||||
|
||||
type HandlerFunc func(http.ResponseWriter, *http.Request, *Route)
|
||||
|
||||
//type Handler http.Handler
|
||||
func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, route *Route) {
|
||||
f(w, r, route)
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
routes []*Route
|
||||
}
|
||||
|
||||
func (h *Router) Get(pattern string, handler HandlerFunc) {
|
||||
h.Handler([]string{"GET"}, regexp.MustCompile(pattern), handler)
|
||||
}
|
||||
|
||||
func (h *Router) Post(pattern string, handler HandlerFunc) {
|
||||
h.Handler([]string{"POST"}, regexp.MustCompile(pattern), handler)
|
||||
}
|
||||
|
||||
func (h *Router) Put(pattern string, handler HandlerFunc) {
|
||||
h.Handler([]string{"PUT"}, regexp.MustCompile(pattern), handler)
|
||||
}
|
||||
|
||||
func (h *Router) Delete(pattern string, handler HandlerFunc) {
|
||||
h.Handler([]string{"DELETE"}, regexp.MustCompile(pattern), handler)
|
||||
}
|
||||
|
||||
func (h *Router) Patch(pattern string, handler HandlerFunc) {
|
||||
h.Handler([]string{"PATCH"}, regexp.MustCompile(pattern), handler)
|
||||
}
|
||||
|
||||
func (h *Router) Options(pattern string, handler HandlerFunc) {
|
||||
h.Handler([]string{"OPTIONS"}, regexp.MustCompile(pattern), handler)
|
||||
}
|
||||
|
||||
func (h *Router) Handler(methods []string, pattern *regexp.Regexp, handler HandlerFunc) {
|
||||
m := make(map[string]int,0)
|
||||
for _, v := range methods {
|
||||
m[v] = 1
|
||||
}
|
||||
h.routes = append(h.routes, &Route{m, pattern, handler})
|
||||
}
|
||||
|
||||
func (h *Router) HandleFunc(methods []string, pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request, *Route)) {
|
||||
m := make(map[string]int,0)
|
||||
for _, v := range methods {
|
||||
m[v] = 1
|
||||
}
|
||||
h.routes = append(h.routes, &Route{m, pattern, HandlerFunc(handler)})
|
||||
}
|
||||
|
||||
func (h *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
for _, route := range h.routes {
|
||||
if route.Pattern.MatchString(r.URL.Path) {
|
||||
_, ok := route.Methods[r.Method]
|
||||
if ok {
|
||||
route.Handler.ServeHTTP(w, r, route)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// no pattern matched; send 404 response
|
||||
http.NotFound(w, r)
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"net/http"
|
||||
"strings"
|
||||
"github.com/ian-kent/MailHog/mailhog/config"
|
||||
"github.com/ian-kent/MailHog/mailhog/http/api"
|
||||
"github.com/ian-kent/MailHog/mailhog/http/handler"
|
||||
"github.com/ian-kent/MailHog/mailhog/http/router"
|
||||
)
|
||||
|
||||
var exitChannel chan int
|
||||
|
@ -14,37 +13,37 @@ var cfg *config.Config
|
|||
|
||||
// TODO clean this mess up
|
||||
|
||||
func web_exit(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func web_exit(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
web_headers(w)
|
||||
w.Write([]byte("Exiting MailHog!"))
|
||||
exitChannel <- 1
|
||||
}
|
||||
|
||||
func web_index(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func web_index(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
web_headers(w)
|
||||
data, _ := cfg.Assets("assets/templates/index.html")
|
||||
w.Write([]byte(web_render(string(data))))
|
||||
}
|
||||
|
||||
func web_jscontroller(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func web_jscontroller(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
w.Header().Set("Content-Type", "text/javascript")
|
||||
data, _ := cfg.Assets("assets/js/controllers.js")
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func web_imgcontroller(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func web_imgcontroller(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
data, _ := cfg.Assets("assets/images/hog.png")
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func web_img_github(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func web_img_github(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
data, _ := cfg.Assets("assets/images/github.png")
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func web_img_ajaxloader(w http.ResponseWriter, r *http.Request, route *handler.Route) {
|
||||
func web_img_ajaxloader(w http.ResponseWriter, r *http.Request, route *router.Route) {
|
||||
w.Header().Set("Content-Type", "image/gif")
|
||||
data, _ := cfg.Assets("assets/images/ajax-loader.gif")
|
||||
w.Write(data)
|
||||
|
@ -67,17 +66,18 @@ func Start(exitCh chan int, conf *config.Config) {
|
|||
exitChannel = exitCh
|
||||
cfg = conf
|
||||
|
||||
r := &router.Router{}
|
||||
server := &http.Server{
|
||||
Addr: conf.HTTPBindAddr,
|
||||
Handler: &handler.RegexpHandler{},
|
||||
Handler: r,
|
||||
}
|
||||
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/exit/?$"), web_exit)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/js/controllers.js$"), web_jscontroller)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/images/hog.png$"), web_imgcontroller)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/images/github.png$"), web_img_github)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/images/ajax-loader.gif$"), web_img_ajaxloader)
|
||||
server.Handler.(*handler.RegexpHandler).HandleFunc([]string{"GET"},regexp.MustCompile("^/$"), web_index)
|
||||
r.Get("^/exit/?$", web_exit)
|
||||
r.Get("^/js/controllers.js$", web_jscontroller)
|
||||
r.Get("^/images/hog.png$", web_imgcontroller)
|
||||
r.Get("^/images/github.png$", web_img_github)
|
||||
r.Get("^/images/ajax-loader.gif$", web_img_ajaxloader)
|
||||
r.Get("^/$", web_index)
|
||||
|
||||
api.CreateAPIv1(exitCh, conf, server)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue