一尘不染

覆盖ResponseWriter接口以捕获HTTP错误

go

我正在用Go编写Web应用程序的代码,尽管各种mux库提供了一种设置自定义404错误处理程序的方法,但其他4xx和5xx错误代码却一无所获。

一种建议是在ResponseWriter界面中重写WriteHeader方法并检查状态代码,但是我对如何实际写入感到困惑(在输出之前重写ResponseWriter方法)。从negroni包中可以找到一个可能的例子。

这是为4xx和5xx错误提供自定义模板的正确方法吗?谁能提供一个示例说明如何实现?

更新资料

非常感谢David和elithrar的回复和代码。InterceptorDavid编码的结构可以在服务器多路复用器的包装器中使用,如elithrar在注释中所示。对于那些寻求进一步解释其原因和方式的人,astaxie的书中的这一节提供了有关net /
http包工作原理的一些很好的信息,以及从net /
http包中查看server.go源代码


阅读 157

收藏
2020-07-02

共1个答案

一尘不染

Mux库只有一种设置未找到的处理程序的方法,它为您提供了一种在Mux无法将URL解析为其已知映射的情况下拦截请求的方法。

例如,您这样做:

mux.Handle("/foo",fooFunc)
mux.Handle("/bar",barFunc)

但是客户端访问/baz的多路复用器没有映射。

他们实际上并没有截取去往客户端的404,而只是在遇到此问题时调用未找到的处理程序。

此外,如果/ foo处理程序发送404响应,则不会调用未找到的响应。

如果您希望自定义页面用于来自映射URL的各种返回响应,只需使各种处理程序编写正确的响应即可。

如果您不控制该逻辑(即:框架正在写东西并且没有覆盖方法),则您可能希望拦截所有请求并使用响应代码检测逻辑覆盖http.ResposeWriter。

这是一个示例拦截器,基本上可以满足您的要求。在播放

package main

import (
    "fmt"
    "log"
)
import "net/http"

type Interceptor struct {
    origWriter http.ResponseWriter
    overridden bool
}

func (i *Interceptor) WriteHeader(rc int) {
    switch rc {
    case 500:
        http.Error(i.origWriter, "Custom 500 message / content", 500)
    case 404:
        http.Error(i.origWriter, "Custom 404 message", 404)
    case 403:
        i.origWriter.WriteHeader(403)
        fmt.Fprintln(i.origWriter, "Custom 403 message")
    default:
        i.origWriter.WriteHeader(rc)
        return
    }
    // if the default case didn't execute (and return) we must have overridden the output
    i.overridden = true
    log.Println(i.overridden)
}

func (i *Interceptor) Write(b []byte) (int, error) {
    if !i.overridden {
        return i.origWriter.Write(b)
    }

    // Return nothing if we've overriden the response.
    return 0, nil
}

func (i *Interceptor) Header() http.Header {
    return i.origWriter.Header()
}
2020-07-02