我正在尝试做一个负载均衡器来研究一些go软件包。
我想在请求超时时处理错误,或者给出404错误,但找不到解决方法。
func main() {
// start server
http.HandleFunc("/", handleRequestAndRedirect)
if err := http.ListenAndServe(getListenAddress(), nil); err != nil {
panic(err)
}
}
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
ur, _ := url.Parse("https://www.instagram.com/")
proxy := httputil.NewSingleHostReverseProxy(ur)
// Update the headers to allow for SSL redirection
req.URL.Host = ur.Host
req.URL.Scheme = ur.Scheme
req.Header.Set("X-Forwarded-Host", req.Header.Get("Host"))
req.Host = ur.Host
req.Header.Set("Key", "Teste")
proxy.ServeHTTP(res, req)
}
答案 0 :(得分:1)
当我最终在这里寻找一种方法来处理来自代理主机的 404 错误时,我想补充已接受的答案,如果它对登陆此页面的人有帮助的话。
如官方文档 (https://golang.org/pkg/net/http/httputil/#ReverseProxy) 所述:
<块引用>ModifyResponse 是一个可选函数,用于修改来自后端的 Response。如果后端完全返回响应并带有任何 HTTP 状态代码,则调用它。 如果后端无法访问,则调用可选的 ErrorHandler 而不调用 ModifyResponse。如果 ModifyResponse 返回错误,则调用 ErrorHandler 及其错误值。如果 ErrorHandler 为 nil,则使用其默认实现。
因此,如果您不仅要捕获“真实”错误(主机无法访问),还要捕获来自服务器的错误响应代码(404、500...),您应该使用 ModifyResponse
检查响应状态代码并返回一个错误,然后您的 ErrorHandler
函数会捕获该错误。接受的答案示例变为:
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
ur, _ := url.Parse("https://www.instagram.com/")
proxy := httputil.NewSingleHostReverseProxy(ur)
// Update the headers to allow for SSL redirection
req.URL.Host = ur.Host
req.URL.Scheme = ur.Scheme
req.Header.Set("X-Forwarded-Host", req.Header.Get("Host"))
req.Host = ur.Host
req.Header.Set("Key", "Teste")
proxy.ErrorHandler = ErrHandle
proxy.ModifyResponse = ModifyResponse
proxy.ServeHTTP(res, req)
}
func ModifyResponse(res *http.Response) error {
if res.StatusCode == 404 {
return errors.New("404 error from the host")
}
return nil
}
func ErrHandle(res http.ResponseWriter, req *http.Request, err error) {
fmt.Println(err)
}
答案 1 :(得分:0)
使用proxy.ErrorHandler
ErrorHandler func(http.ResponseWriter,* http.Request,错误)
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
ur, _ := url.Parse("https://www.instagram.com/")
proxy := httputil.NewSingleHostReverseProxy(ur)
// Update the headers to allow for SSL redirection
req.URL.Host = ur.Host
req.URL.Scheme = ur.Scheme
req.Header.Set("X-Forwarded-Host", req.Header.Get("Host"))
req.Host = ur.Host
req.Header.Set("Key", "Teste")
proxy.ErrorHandler = ErrHandle
proxy.ServeHTTP(res, req)
}
func ErrHandle(res http.ResponseWriter, req *http.Request, err error) {
fmt.Println(err)
}