53 lines
1.3 KiB
Go
53 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"regexp"
|
|
"slices"
|
|
)
|
|
|
|
type URLParam struct{}
|
|
|
|
var routes = []struct {
|
|
methods []string
|
|
regex *regexp.Regexp
|
|
handler http.HandlerFunc
|
|
}{
|
|
{[]string{"GET"}, url(""), index},
|
|
{[]string{"GET"}, url("/(pgp.asc|ssh)"), static},
|
|
{[]string{"GET"}, url("/static/.+"), static},
|
|
{[]string{"GET"}, url("/(.+\\.(css))"), file},
|
|
{[]string{"GET"}, url("/([^/]+)"), html},
|
|
}
|
|
|
|
func url(s string) *regexp.Regexp {
|
|
return regexp.MustCompile("^" + s + "/?$")
|
|
}
|
|
|
|
func getParam(r *http.Request, i int) string {
|
|
return r.Context().Value(URLParam{}).([]string)[i]
|
|
}
|
|
|
|
func route(w http.ResponseWriter, r *http.Request) {
|
|
for _, rt := range routes {
|
|
matches := rt.regex.FindStringSubmatch(r.URL.Path)
|
|
if len(matches) > 0 {
|
|
if !slices.Contains(rt.methods, r.Method) {
|
|
w.Header().Set("Allow", r.Method)
|
|
http.Error(
|
|
w, "405 method not allowed", http.StatusMethodNotAllowed,
|
|
)
|
|
return
|
|
}
|
|
fmt.Println(r.Method, r.URL.Path)
|
|
rt.handler(w, r.WithContext(
|
|
context.WithValue(r.Context(), URLParam{}, matches[1:]),
|
|
))
|
|
return
|
|
}
|
|
}
|
|
http.NotFound(w, r)
|
|
}
|