Go:如何组合两个(或更多)http.ServeMux?

bgu*_*uiz 3 http go servemux

鉴于您有两个实例http.ServeMux,并希望它们在相同的端口号上提供,如下所示:

    muxA, muxB http.ServeMux
    //initialise muxA
    //initialise muxB
    combinedMux := combineMux([muxA, muxB])
    http.ListenAndServe(":8080", combinedMux)
Run Code Online (Sandbox Code Playgroud)

combinedMux如上所述,如何编写函数?

......还是有另一种方法来完成同样的事情?

小智 6

因为a http.ServeMuxhttp.Handler可以轻松地将一个mux嵌套在另一个mux中,即使在同一个端口和相同的主机名上也是如此.这是一个这样做的例子:

rootMux := http.NewServeMux()
subMux := http.NewServeMux()

// This will end up handling /top_path/sub_path
subMux.HandleFunc("/sub_path", myHandleFunc)

// Use the StripPrefix here to make sure the URL has been mapped
// to a path the subMux can read
rootMux.Handle("/top_path/", http.StripPrefix("/top_path", subMux))

http.ListenAndServe(":8000", rootMux)
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有该http.StripPrefix()调用,您将需要处理较低多路复用器中的整个路径.


tux*_*21b 4

SeverMux 类型本身就是一个 http.Handler,因此您可以轻松嵌套它们。例如:

mux := NewServeMux()
mux.AddHandler("server1.com:8080/", muxA)
mux.AddHandler("server2.com:8080/", muxB)
Run Code Online (Sandbox Code Playgroud)

我不太确定“组合”它们到底是什么意思。如果您想先尝试一个处理程序,然后在出现 404 错误时尝试另一个处理程序,您可以这样做(未经测试):

mux := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    rec := httptest.NewRecorder()
    rec.Body = &bytes.Buffer{}
    muxA.ServeHTTP(rec, r)
    if rec.Code == 404 {
        muxB.ServeHTTP(w, r)
        return
    }
    for key, val := range rec.HeaderMap {
        w.Header().Set(key, val)
    }
    w.WriteHeader(rec.Code)
    rec.Body.WriteTo(w)
})
Run Code Online (Sandbox Code Playgroud)

这显然有一些缺点,例如将整个响应存储在内存中。或者,如果您不介意调用处理程序两次,您也可以设置rec.Body = nil,仅检查并在成功时再次rec.Code调用。muxA.ServeHTTP(w, r)但最好重构您的应用程序,以便第一种方法(嵌套 ServerMux)就足够了。