我通过 Go Web 服务器提供 Web 内容,并使用正则表达式将处理程序匹配到请求路径。我注意到我在下面的测试代码中稀释了一个非常奇怪的行为。基本上,任何 8 个字母/数字组合都意味着被处理程序捕获,而其他特定的请求路径意味着被其他处理程序捕获。这在 8 个字母/数字路径的情况下非常有效,如果字母序列以小写“c”结尾,则匹配被第一个处理程序拾取。最后的任何其他字母都可以正常工作。
下面的代码可以粘贴到文件中并运行。它将在 localhost:8080 上提供服务。我提供了一些请求链接来演示该问题。
package main
import (
"fmt"
"net/http"
"regexp"
)
// This is the handler when passing a string of 8 characters ([])
func runTest(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path[1:]
fmt.Fprintf(w, path)
}
func runTest2(w http.ResponseWriter, r *http.Request) {
path := "Reg ex for: .[(css|jpg|png|js|ttf|ico)]$"
fmt.Fprintf(w, path)
}
func runTest3(w http.ResponseWriter, r *http.Request) {
path := "Reg ex for: /all$"
fmt.Fprintf(w, path)
}
// Regular expression handler
type route struct {
pattern *regexp.Regexp
handler http.Handler
}
type RegexpHandler struct {
routes []*route
}
func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
h.routes = append(h.routes, &route{pattern, handler})
}
func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
}
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, route := range h.routes {
if route.pattern.MatchString(r.URL.Path) {
route.handler.ServeHTTP(w, r)
return
}
}
http.NotFound(w, r)
}
func main() {
handler := &RegexpHandler{}
handler.HandleFunc(regexp.MustCompile(`.[(css|jpg|png|js|ttf|ico)]$`), runTest2)
handler.HandleFunc(regexp.MustCompile("^/all$"), runTest3)
handler.HandleFunc(regexp.MustCompile("^/[A-Z0-9a-z]{8}$"), runTest)
http.ListenAndServe(":8080", handler)
}
此请求被第二个处理程序 (runTest3) 接收:
http://localhost:8080/all
这个请求被第三个处理程序(runTest)接收,它打印出 url 的路径部分:
http://localhost:8080/yr22FBMD.
然而,这个请求被第一个处理程序接收(注意它以小写 c 结尾):
http://localhost:8080/yr22FBMc
有任何想法吗?这非常奇怪!