when to use hijack in golang?

15.5k views Asked by At

I don't understand why we use hijack, since I can write something into response body directly, could anyone explain this?

func writeSome(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "write some thing")
}

it is same as this:

func hijack(w http.ResponseWriter, r *http.Request) {
    hj, _ := w.(http.Hijacker)
    _, buf, _ := hj.Hijack()
    buf.WriteString("write some thing")
    buf.Flush()
}

I am confused

2

There are 2 answers

5
VonC On

You can see one library (martini) which introduced hijack: issue 45
(Note: I don't recommend Martini, which is not idiomatic, but it is mentioned here only to illustrate hijack)

Would it be possible for your responseWriter type to implement http.Hijack?
This would allow libraries like this websockets one to work with martini.

That issue refers to the following go-nuts thread, where one tried to embed the interface http.ResponseWriter in order to record statistics like bytes written and request duration.

Later on somebody pointed out some other interesting features of the http library, such as the CloseNotifier interface, and I realized the above code might not be such a good idea.
Since I'm embedding an interface, I can't automatically inherit *http.Response's implementations of CloseNotifier and Flusher.

So, if you want to take over the ResponseWriter in order to:

  • record more information (status, size, ..., calling hijack is probably overkill here),
  • implement another protocol (like websocket, which "Upgrade" an HTTP server connection, calling w.(http.Hijacker))

Then you can consider using hijack.
But, as documented, 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.

If not, as illustrating in this other question, then hijack isn't interesting.

0
Mixcels On

Use Hijack when you don't want to use the built-in server's implementation of the HTTP protocol. This might be because you want to switch protocols (to WebSocket for example) or the built-in server is getting in your way.

The two snippets of code above do not create the same output on the wire. The output from the first snippet will include a response header:

HTTP/1.1 200 OK
Date: Wed, 26 Nov 2014 03:37:57 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8

write some thing

The second snippet bypasses the built-in server code and writes

write some thing

directly to the output.