如果请求路径包含附加斜杠,则 Golang “301 Moved Permanently”

Posted

技术标签:

【中文标题】如果请求路径包含附加斜杠,则 Golang “301 Moved Permanently”【英文标题】:Golang "301 Moved Permanently" if request path contains additional slash 【发布时间】:2018-05-08 14:49:58 【问题描述】:

我一直在使用 golang 的默认 http.ServeMux 进行 http 路由处理。

wrap := func(h func(t *MyStruct, w http.ResponseWriter, r *http.Request)) func(http.ResponseWriter, *http.Request) 
    return func(w http.ResponseWriter, r *http.Request) 
        h(t, w, r)
    


// Register handlers with default mux
httpMux := http.NewServeMux()
httpMux.HandleFunc("/", wrap(payloadHandler))

假设这个服务器可以通过http://example.com/访问

我的客户请求中很少有路径http://example.com/api//module(注意额外的斜杠)被重定向为301 Moved Permanently。探索 golang 的 http ServeMux.Handler(r *Request) 函数内部,似乎是有意的。

path := cleanPath(r.URL.Path)
// if there is any change between actual and cleaned path, the request is 301 ed
if path != r.URL.Path 
    _, pattern = mux.handler(host, path)
    url := *r.URL
    url.Path = path
    return RedirectHandler(url.String(), StatusMovedPermanently), pattern

我已经研究过其他类似的问题。

go-web-server-is-automatically-redirecting-post-requests

上面的 qn 在寄存器模式本身存在冗余/ 的问题,但我的用例不是寄存器模式(在一些与寄存器模式无关的嵌套路径中)

问题是,由于我的客户的请求是POST,浏览器会使用带有精确查询参数和POST 正文的新GET 请求来处理301。但是更改 HTTP 方法会导致请求失败。

我已经指示客户修复 url 中多余的 /,但修复可能需要几个 (?) 周才能部署到所有客户端位置。

这些多余的/Apache Tomcat 中也可以很好地处理,但仅在 golang 服务器中失败。那么这是我的用例中的预期行为(嵌套路径中的冗余 /)与 golang 或可能的错误?

我正在考虑覆盖ServeMuxHandler 函数的方法,但它不会有用,因为Handler 调用是在内部进行的。希望禁用此 301 行为,我们将不胜感激。

相关链接

http-post-method-is-actally-sending-a-get

【问题讨论】:

【参考方案1】:

干净和重定向是预期的行为。

使用删除双斜杠的处理程序包装多路复用器:

type slashFix struct 
    mux http.Handler


func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) 
    r.URL.Path = strings.Replace(r.URL.Path, "//", "/", -1)
    h.mux.ServeHTTP(w, r)

像这样使用它:

httpMux := http.NewServeMux()
httpMux.HandleFunc("/", wrap(payloadHandler))
http.ListenAndServe(addr, &slashFixhttpMux)

【讨论】:

首先我使用了 Gorilla Mux,但在看到这个之后.. 让我开心..!【参考方案2】:

接受的答案解决了问题

另一种方法是使用Gorilla mux 并设置SkipClean(true)。但请务必了解其doc中的副作用

SkipClean 定义了新路由的路径清理行为。初始值为假。用户应该注意哪些路由没有被清理。当为真时,如果路由路径是“/path//to”,它将保留双斜杠。如果您有这样的路线,这将很有帮助:/fetch/http://xkcd.com/534/

当为false时,路径会被清理,所以/fetch/http://xkcd.com/534/会变成/fetch/http/xkcd.com/534

func (r *Router) SkipClean(value bool) *Router 
    r.skipClean = value
    return r

【讨论】:

以上是关于如果请求路径包含附加斜杠,则 Golang “301 Moved Permanently”的主要内容,如果未能解决你的问题,请参考以下文章

003-golang 调用外部命令

路径部分中带有 // 的 URL 是不是有效?

双反斜杠不起作用?

由于文件路径中的附加斜杠,未找到 Spring 占位符 (.properties)

文件路径中正斜杠 (/) 和反斜杠 (\) 之间的区别

Wordpress 路径不包含斜杠