dpg98445 2017-11-24 14:59
浏览 220
已采纳

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

I have been using golang's default http.ServeMux for http route handling.

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))

Assume this server is accessible via http://example.com/

Very few of my client's requests were of path http://example.com/api//module (note the extra slash) which is redirected as 301 Moved Permanently. Exploring inside golang's http ServeMux.Handler(r *Request) function, seems it's intended.

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
}

I've looked into other similar issue.

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

Above qn has problem with redundant / in register pattern itself, but my use case is not with register pattern (in some nested path which is irrelevent to register pattern)

Problem is, since my client's requests are POST, browsers handle 301 with new GET request with exact query params and POST body. But change in the HTTP method causes the request to fail.

I have already instructed client to fix the redundant / in url, but the fix might take few (?) weeks to be deployed in all client locations.

Also these redundant / are handled fine in Apache Tomcat, but fails only in golang server. So is this the intended behaviour in my use case (redundant / in nested path) with golang or possible bug?

I am thinking of way to override the Handler func of ServeMux, but it won't be useful since Handler calls are made internally. Looking to disable this 301 behaviour, help would be appreciated.

Relevant links

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

  • 写回答

2条回答 默认 最新

  • 普通网友 2017-11-24 15:11
    关注

    The clean and redirect is intended behavior.

    Wrap the mux with a handler that removes the double slashes:

    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)
    }
    

    Use it like this:

    httpMux := http.NewServeMux()
    httpMux.HandleFunc("/", wrap(payloadHandler))
    http.ListenAndServe(addr, &slashFix{httpMux})
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛