我需要在Web服务器的处理程序中自定义HTTP状态,但是我发现golang似乎不支持完全自定义的HTTP响应。 例如:
w.WriteHeader(999)
这是curl
的结果:
$ curl -vk -i localhost:9898/hello
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 9898 (#0)
> GET /hello HTTP/1.1
> Host: localhost:9898
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 999 status code 999
HTTP/1.1 999 status code 999
< Date: Wed, 19 Jun 2019 02:01:09 GMT
Date: Wed, 19 Jun 2019 02:01:09 GMT
< Content-Length: 0
Content-Length: 0
结果中的status code
似乎无法修改..但是,我想定义自己的状态,例如Bad Request: xxx
。
有什么好主意吗?非常感谢!
答案 0 :(得分:6)
我不认为您正在尝试的内容目前不受支持。
根据the official documentation of net/http.ResponseWriter.WriteHeader
:
提供的代码必须是有效的HTTP 1xx-5xx状态代码。只能写入一个标题。 Go目前不支持发送用户定义的1xx信息性标头,但100连续响应标头是服务器在读取Request.Body时自动发送的。
答案 1 :(得分:3)
此功能在net/http/server.go中处理:
func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) {
if is11 {
bw.WriteString("HTTP/1.1 ")
} else {
bw.WriteString("HTTP/1.0 ")
}
if text, ok := statusText[code]; ok {
bw.Write(strconv.AppendInt(scratch[:0], int64(code), 10))
bw.WriteByte(' ')
bw.WriteString(text)
bw.WriteString("\r\n")
} else {
// don't worry about performance
fmt.Fprintf(bw, "%03d status code %d\r\n", code, code)
}
}
由此您可以看到,描述性文本来自标准库的内部状态码列表,这些内容由StatusText函数公开。
如果没有已知的文本,则使用占位符“状态代码”,没有任何选项可以更改此行为。
因此,使用标准库http
程序包,您无法做您想要的事情。您可以选择在您自己的程序包中分叉和/或重新实现此功能,或者(可能是长期的)向上游提交功能请求以更改此功能。
如果出于某种原因确实需要此功能,那么最后一种绝望的方法可能是编写某种代理,该代理可以拦截HTTP输出并为您转换“状态代码”文本。您可以通过编写自己的net.Listener
实现/包装器来实现此目的,然后将其传递给http.Serve
。除非您绝对没有其他选择,否则这将不会非常有效,并且不建议这样做。