什么时候在golang中使用劫持?

时间:2014-11-22 08:25:04

标签: go go-http

我不明白为什么我们使用劫持,因为我可以直接在响应体中写一些东西,有人可以解释一下吗?

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

它与此相同:

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

我很困惑

2 个答案:

答案 0 :(得分:15)

当您不想使用内置服务器的HTTP协议实现时,请使用Hijack。这可能是因为您想要切换协议(例如,转换为WebSocket),或者内置服务器正在妨碍您。

上面两段代码不会在线路上创建相同的输出。第一个代码段的输出将包含响应标头:

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

第二个代码段绕过内置服务器代码并写入

write some thing

直接输出。

答案 1 :(得分:4)

您可以看到一个引入hijack martini的图书馆(issue 45) (注意:我不推荐Martini,which is not idiomatic,但此处仅提及hijack

  

你的responseWriter类型是否可以实现http.Hijack?
  这将允许像websockets one这样的库与马提尼一起使用。

该问题涉及following go-nuts thread,其中一个试图嵌入接口http.ResponseWriter以记录写入的字节和请求持续时间等统计信息。

  

后来有人指出了http库的其他一些有趣的功能,比如CloseNotifier接口,我意识到上面的代码可能不是一个好主意。
  由于我正在嵌入接口,因此我无法自动继承*http.ResponseCloseNotifier的{​​{1}}实现。

所以,如果您想接管Flusher以便:

  • 记录更多信息(状态,大小......,此处调用劫持可能有点过头了),
  • 实现另一个协议(如websocket,“Upgrade”HTTP服务器连接,calling w.(http.Hijacker)

然后你可以考虑使用劫持 但是,as documented,在调用ResponseWriter之后,HTTP服务器库将不会对连接执行任何其他操作。
调用者有责任管理和关闭连接。

如果没有,如图in this other question所示,则劫持并不有趣。