I want to use hijack in golang, while recieve invalid response on client
func hijack(w http.ResponseWriter, r *http.Request) {
fmt.Println("start")
hj, ok := w.(http.Hijacker)
fmt.Println(ok)
c, buf, err := hj.Hijack()
if err != nil {
panic(err)
}
n, err := buf.Write([]byte("hello"))
if err != nil {
panic(err)
}
fmt.Println("n == ",n)
err = buf.Flush()
if err != nil {
panic(err)
}
fmt.Println("end")
}
follow printed on server:
start
true
n == 5
end
but I got following error on the client
localhost sent an invalid response. ERR_INVALID_HTTP_RESPONSE
As the Hijacker
's documentation says
Hijack lets the caller take over the connection. After a call to Hijack the HTTP server library will not do anything else with the connection.
It becomes the caller's responsibility to manage and close the connection.
The returned net.Conn may have read or write deadlines already set, depending on the configuration of the Server. It is the caller's responsibility to set or clear those deadlines as needed.
The returned bufio.Reader may contain unprocessed buffered data from the client.
After a call to Hijack, the original Request.Body must not be used. The original Request's Context remains valid and is not canceled until the Request's ServeHTTP method returns.
You need to write to c
rather than buf
. And you need to write response status and Content-Length
header.
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fmt.Println("start")
writer.Header().Add("Content-Length", "5")
writer.WriteHeader(200)
hj, ok := writer.(http.Hijacker)
fmt.Println(ok)
c, _, err := hj.Hijack()
if err != nil {
panic(err)
}
n, err := c.Write([]byte("hello"))
if err != nil {
panic(err)
}
fmt.Println("n == ",n)
err = c.Close()
if err != nil {
panic(err)
}
fmt.Println("end")
})