如果请求路径包含其他斜杠,则Golang“301永久移动”

时间:2017-11-24 14:59:30

标签: http redirect go http-status-code-301

我一直在使用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方法的更改会导致请求失败。

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

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

我正在考虑覆盖Handler的{​​{1}} func,但由于ServeMux调用是在内部进行的,因此无效。想要禁用这301行为,将不胜感激。

相关链接

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

1 个答案:

答案 0 :(得分:0)

已接受的答案解决了问题

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

中的副作用
  

SkipClean定义新路由的路径清理行为。初始值为false。用户应该注意不清理哪些路由。如果为true,如果路径路径为" / 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
}