when to use hijack in golang?
Asked Answered
T

2

23

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

Terryn answered 22/11, 2014 at 8:25 Comment(0)
A
30

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.

Amative answered 26/11, 2014 at 3:39 Comment(0)
R
8

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.

Richers answered 22/11, 2014 at 8:47 Comment(5)
I wouldn't suggest you to use Martini because it is not idiomatic to GoFlaxseed
@Flaxseed I know, and I have edited the answer to make that clear. You can revert your downvote now.Richers
@Flaxseed That is strange: you still have not reverted your downvote. Is there something missing?Richers
Link on ?my thoughts on martini" now links to a bet365 spam, does anybody have the original article?Accordion
@FelipeValdes Thank you. I have restored the link to the article "My Thoughts on Martini"Richers

© 2022 - 2024 — McMap. All rights reserved.