如何在Golang的net/http中使路径”/”不匹配所有其他不匹配的路径?

huangapple go评论82阅读模式
英文:

How to make path "/" dont match all others not matched paths in Golang net/http

问题

我正在使用golang的net/http包创建一些API的端点。

我有一个映射到/路径的index函数。我希望任何没有明确声明给muxpath都返回404

文档中提到:

请注意,由于以斜杠结尾的模式表示根子树,因此模式"/"匹配所有未被其他注册模式匹配的路径,而不仅仅是Path为"/"的URL。

那么,我该如何做到这一点?

以下是一个最小可复现示例(MRE):

package main

import (
	"fmt"
	"log"
	"net/http"
)

func index(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "index")
}

func foo(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "foo")
}

func bar(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "bar")
}

func main() {

	mux := http.NewServeMux()

	s := &http.Server{
		Addr:    ":8000",
		Handler: mux,
	}

	mux.HandleFunc("/", index)
	mux.HandleFunc("/foo", foo)
	mux.HandleFunc("/bar", bar)

	log.Fatal(s.ListenAndServe())
}

当我运行时:

$ curl 'http://localhost:8000/'
index

$ curl 'http://localhost:8000/foo'
foo

$ curl 'http://localhost:8000/bar'
bar

$ curl 'http://localhost:8000/notfoo'
index // 期望得到404页面未找到
英文:

I'm using golang net/http to create some endpoints in an API.

I have an index function mapped to / path. I need any path that was not explicitly declared to mux to return 404.

The docs says:

> Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".

So, how can I do this?

Follows a MRE:

package main

import (
	"fmt"
	"log"
	"net/http"
)

func index(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "index")
}

func foo(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "foo")
}

func bar(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "bar")
}

func main() {

	mux := http.NewServeMux()

	s := &http.Server{
		Addr:    ":8000",
		Handler: mux,
	}

	mux.HandleFunc("/", index)
	mux.HandleFunc("/foo", foo)
	mux.HandleFunc("/bar", bar)

	log.Fatal(s.ListenAndServe())
}

When I run:

$ curl 'http://localhost:8000/'
index

$ curl 'http://localhost:8000/foo'
foo

$ curl 'http://localhost:8000/bar'
bar

$ curl 'http://localhost:8000/notfoo'
index // Expected 404 page not found

答案1

得分: 4

由于您使用的 mux 将 "/ "处理程序与任何未注册的处理程序匹配,所以每次调用 "/ "路径的处理程序时,您都需要检查路径:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func index(w http.ResponseWriter, req *http.Request) {
    if req.URL.Path != "/" { // 在这里检查路径
       http.NotFound(w, req)
       return
    }
    fmt.Fprintln(w, "index")
}

func foo(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "foo")
}

func bar(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "bar")
}

func main() {

    mux := http.NewServeMux()

    s := &http.Server{
        Addr:    ":8000",
        Handler: mux,
    }

    mux.HandleFunc("/foo", foo)
    mux.HandleFunc("/bar", bar)
    mux.HandleFunc("/", index)

    log.Fatal(s.ListenAndServe())
}
英文:

Since the mux you are using will match the / handler to any unregistered one, you'll have to check the path anytime your handler for the / path is called:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func index(w http.ResponseWriter, req *http.Request) {
    if req.URL.Path != "/" { // Check path here
       http.NotFound(w, req)
       return
    }
    fmt.Fprintln(w, "index")
}

func foo(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "foo")
}

func bar(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "bar")
}

func main() {

    mux := http.NewServeMux()

    s := &http.Server{
        Addr:    ":8000",
        Handler: mux,
    }

    mux.HandleFunc("/foo", foo)
    mux.HandleFunc("/bar", bar)
    mux.HandleFunc("/", index)

    log.Fatal(s.ListenAndServe())
}

huangapple
  • 本文由 发表于 2022年4月29日 05:07:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/72050229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定