I need to customize the HTTP Status in a handler in my Web Server, but I found that golang doesn't seem to support completely custom HTTP Response.. For example:
w.WriteHeader(999)
here is the curl
result:
$ 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
the status code
in the result seems couldn't be modified.. but, I want to define my own status, like Bad Request: xxx
.
Is there any good ideas? Thanks a lot!
I don't think what you're trying is currently supported.
As per the official documentation of net/http.ResponseWriter.WriteHeader
:
The provided code must be a valid HTTP 1xx-5xx status code. Only one header may be written. Go does not currently support sending user-defined 1xx informational headers, with the exception of 100-continue response header that the Server sends automatically when the Request.Body is read.
This functionality is handled in 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("
")
} else {
// don't worry about performance
fmt.Fprintf(bw, "%03d status code %d
", code, code)
}
}
From this you can see that the descriptive text comes from the standard library's internal list of status codes, the same exposed by the StatusText function.
If there is no known text, the place-holder "status code" is used, with no option to change this behavior.
So with the standard library http
package, there is no way to do what you desire. Your options are to fork and/or re-implement this functionality in your own package, or (possibly a long-shot), submit a feature request upstream to change this functionality.
If this functionality is really necessary for some reason, one last-ditch, desperate approach might be to write some sort of proxy, that intercepts the HTTP output, and transforms the 'status code' text for you. You might be able to do this by writing your own implementation/wrapper of net.Listener
, which you then pass to http.Serve
. This won't be very efficient, and is highly discouraged, unless you have absolutely no other option.