92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
)
|
|
|
|
type HandlerFuncWithError = func (http.ResponseWriter, *http.Request) error
|
|
|
|
type HttpMethod string
|
|
|
|
const(
|
|
HttpGet HttpMethod = "GET"
|
|
HttpPost HttpMethod = "POST"
|
|
)
|
|
|
|
type RequestContext struct {
|
|
ResponseWriter http.ResponseWriter
|
|
Request *http.Request
|
|
MethodType HttpMethod
|
|
Pattern string
|
|
}
|
|
|
|
type Router struct {
|
|
patterns map[string] *PatternRouter
|
|
}
|
|
|
|
type PatternRouter struct {
|
|
Get HandlerFuncWithError
|
|
Post HandlerFuncWithError
|
|
}
|
|
|
|
func (p *Router) MethodFuncForPattern(methodType HttpMethod, pattern string) (HandlerFuncWithError, error) {
|
|
var methodFunc HandlerFuncWithError
|
|
switch methodType {
|
|
case HttpGet:
|
|
methodFunc = p.patterns[pattern].Get
|
|
case HttpPost:
|
|
methodFunc = p.patterns[pattern].Post
|
|
}
|
|
if methodFunc == nil {
|
|
return nil, fmt.Errorf("method %s not defined on pattern %s", methodType, pattern)
|
|
}
|
|
return methodFunc, nil
|
|
}
|
|
|
|
func (p *Router) setGet(pattern string, cb HandlerFuncWithError) {
|
|
if _, ok := p.patterns[pattern]; ok {
|
|
p.patterns[pattern].Get = cb
|
|
} else {
|
|
p.patterns[pattern] = &PatternRouter{cb, nil}
|
|
http.HandleFunc(pattern, getPatternHandler(pattern))
|
|
}
|
|
}
|
|
|
|
func (p *Router) setPost(pattern string, cb HandlerFuncWithError) {
|
|
if _, ok := p.patterns[pattern]; ok {
|
|
p.patterns[pattern].Post = cb
|
|
} else {
|
|
p.patterns[pattern] = &PatternRouter{nil, cb}
|
|
http.HandleFunc(pattern, getPatternHandler(pattern))
|
|
}
|
|
}
|
|
|
|
var MainRouter = Router{make(map[string] *PatternRouter)}
|
|
|
|
func getPatternHandler(pattern string) http.HandlerFunc {
|
|
return func (w http.ResponseWriter, r *http.Request) {
|
|
cb, err := MainRouter.MethodFuncForPattern(HttpMethod(r.Method), pattern)
|
|
context := RequestContext{w, r, HttpMethod(r.Method), pattern}
|
|
if err == nil {
|
|
err = cb(w, r)
|
|
}
|
|
if err != nil {
|
|
sendInternalError(err, context)
|
|
}
|
|
}
|
|
}
|
|
|
|
func sendInternalError(err error, context RequestContext) {
|
|
errorMessage := "Internal Server Error!"
|
|
if DEBUG {
|
|
errorMessage += fmt.Sprintf( " Happened during %s request for pattern '%s': %s",
|
|
context.MethodType,
|
|
context.Pattern,
|
|
err.Error())
|
|
}
|
|
fmt.Println(errorMessage)
|
|
http.Error(context.ResponseWriter, errorMessage, 500)
|
|
}
|
|
|