如何针对解析错误自定义Golang http 400响应?

时间:2017-08-21 17:11:12

标签: http go error-handling bad-request media-type

我编写了一个REST API服务,要求所有响应都是JSON。但是,当Go http请求解析器遇到错误时,它会返回400作为纯文本响应,而不会调用我的处理程序。例如:

> curl -i -H 'Authorization: Basic hi    
there' 'http://localhost:8080/test' -v
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /test HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Authorization: Basic hi
> there
> 
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< Content-Type: text/plain; charset=utf-8
Content-Type: text/plain; charset=utf-8
< Connection: close
Connection: close

< 
* Closing connection 0

请注意无效的Authorization标头。当然,400是正确的回应,但当然是文本/简单。有没有办法配置Go http解析器使用自定义错误响应媒体类型和主体?

2 个答案:

答案 0 :(得分:3)

你做不到。您可以在net / http源中找到它,只有在请求格式错误时才会发生:

https://github.com/golang/go/blob/master/src/net/http/server.go#L1744

我认为您的问题可能是您在curl中添加的标题中的新行?

您将能够使用json响应401,403,404,500个错误,但在server.go中处理错误的请求或错误的标头(太长,格式错误)。

目前没有办法拦截这些错误,虽然它位于consideration之下,所以你唯一的解决办法就是修补stdlib源码(我不建议这样做)。但是,由于此错误仅在客户端出错并且请求格式错误时才出现,因此可能不是一个大问题。文本响应的原因是浏览器或类似客户端(如没有-v的curl)不会只看到空响应。你可以在你的应用程序前放置像nginx这样的代理,但是你永远不会看到请求,因为它是一个错误的请求,你的代理会处理它。

如果你设置一个特定的静态错误页面为它服务400个错误并提供你指定的400.json文件,你可能会在前面使用像nginx这样的代理吗?这是我能想到的唯一解决方案。像这样的指令可能适用于nginx:

error_page 400 /400.json;

如果您希望能够自定义这些错误,可以在链接的问题上添加注释,让他们知道您遇到了这个特定问题。

答案 1 :(得分:-1)

如果您使用的是标准网络/ http库,则可以使用以下代码。看一下我从

获得这个例子的答案Showing custom 404 error page with standard http package @Mostafa
func homeHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        errorHandler(w, r, http.StatusNotFound)
        return
    }
    fmt.Fprint(w, "welcome home")
}

func errorHandler(w http.ResponseWriter, r *http.Request, status int) {
    w.WriteHeader(status)
    if status == http.StatusNotFound {
        // JSON Out here
    }
}