feat: better route function

This commit is contained in:
ange 2024-12-10 03:04:52 +00:00
parent 805d417a9a
commit aaac5d780b
Signed by: ange
GPG key ID: 9E0C4157BB7BEB1D
10 changed files with 103 additions and 51 deletions

15
src/main.go Normal file
View file

@ -0,0 +1,15 @@
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/", Route)
err := http.ListenAndServe(":3000", nil)
if err != nil {
log.Fatal(err)
}
}

58
src/route.go Normal file
View file

@ -0,0 +1,58 @@
package main
import (
"context"
"fmt"
"net/http"
"path/filepath"
"regexp"
"slices"
)
type URLParam struct{}
type W = http.ResponseWriter
type R = *http.Request
var routes = []struct {
methods []string
regex *regexp.Regexp
handler http.HandlerFunc
}{
{[]string{"GET"}, URL(""), func(w W, r R) {
http.ServeFile(w, r, filepath.Join("html", "index.html"))
}},
{[]string{"GET"}, URL("/style\\.css"), func(w W, r R) {
http.ServeFile(w, r, "/html/style.css")
}},
{[]string{"GET"}, URL("/static/.+"), func(w W, r R) {
http.ServeFile(w, r, r.URL.Path)
}},
{[]string{"GET"}, URL("/[^/]+"), func(w W, r R) {
http.ServeFile(w, r, filepath.Join("html", r.URL.Path + ".html"))
}},
}
func URL(s string) *regexp.Regexp {
return regexp.MustCompile("^" + s + "/?$")
}
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,
)
fmt.Println(r.Method, r.URL.Path)
}
rt.handler(w, r.WithContext(
context.WithValue(r.Context(), URLParam{}, matches[1:])),
)
return
}
}
http.NotFound(w, r)
}