了解Http.Hijacker
Go 的 http 包提供了一个 Hijacker 接口类型,如果我们不想使用 Go 的 http 连接默认行为,我们通过使用这个接口,“劫获” http 连接,并且把它转换成我们自己的管理方式。
一旦我们“劫获”了原来的http连接,我们可以自己操控这个连接(也意味着需要自己处理连接的关闭)。通常,我们还可以把劫获的 http 转换成 websocket 或者 rpc 等方式,
下面看一个简单的例子来比较默认的 http 行为和使用 Hijacker “劫取”之后的行为:
(1) Default http
Request Handler function
|
|
Response:
|
|
(2) After Hijacked
|
|
The message “Hello world!” will be write to the output directly without header part, like below.
Response:
|
|
Notice that both of http.ResponseWriter and http.Hijacker are interfaces, this means w implements both interfaces.
Hijacker prototype
|
|
Let’s see an example to see how we can hijack a normal http request and convert it to RPC protocol.
|
|
Notice that by executing hj.Hijack() we get the conn and buffer reader & writer out of the http connection, we generate a new conn object, which is different from original one, from them by
doing newConn().
newConn is look like this:
|
|
After that we simply run this newly create conn.
|
|
In the above code example (for simplicity, I removed some error checking blocks), a proto buffer response struct is constructed to for the client request, and therefore
the original http transport is switched to RPC communication.
extention
http.Hijacker is also a good learning example on how to use interface in Go.
|
|
In the above example, I emulate two interfaces like the ResponseWriter and Hijacker provided by the Go standard library net/http,
then I define a wter struct to implement both of the interfaces, and pass it in as an argument in testHj function, the type assertion suceeds as expected.
Note: if we use type assertion on a declared type object, we have to store it in a interface variable,
otherwise we will receive errors saying “invalid type assertion: (non-interface type xxx on left)”
|
|
参考
Use http.Hijacker to take over the http connection
Go Hijack黑科技