HTTP1.X、HTTP/2、websocket、http.Hijacker golang

栏目: Html5 · 发布时间: 5年前

  • Go 1.6开始, net/http 下提供的 Server 在调用 ListenAndServeTLS 函数启动https服务的情况下会自动支持HTTP/2。其会根据与客户端TLS握手阶段的ALPN扩展判断客户端是否支持HTTP/2(h2),若支持,在TLS握手结束后会直接使用HTTP/2进行通讯。

  • 若需要使用HTTPS但不想开启HTTP/2可以有以下两种方法:

    • 初始化 Server 结构体时,将 TLSNextProto 字段置为一个非 nil 的空map

      // 栗子
      server := http.Server{
          Addr:         ":8080",
          TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
      }
      log.Fatal(server.ListenAndServeTLS("./ssl/ca.crt", "./ssl/ca.key"))
    • 使用 GODEBUG 环境变量

      GODEBUG=http2client=0  # disable HTTP/2 client support
      GODEBUG=http2server=0  # disable HTTP/2 server support
      GODEBUG=http2debug=1   # enable verbose HTTP/2 debug logs
      GODEBUG=http2debug=2   # ... even more verbose, with frame dumps

  • 也就是说默认提供的 http.Server 仅在启用https时才会支持HTTP/2,也就是只支持h2模式。若要使用h2c模式,需要使用 golang.org/x/net/http2 中提供的API。(P.S:目前大多数浏览器仅支持h2模式)

  • WebSocket和HTTP/2不兼容,如果想让WebSocket跑在TLS上,需要用上面的方法禁用HTTP/2

    • 原因分析:

      • 在HTTP1.X中,一个请求和回复对应在一个tcp连接上,在websocket握手结束后,该tcp链接升级为websocket协议。而在HTTP/2中,多个请求和回复会复用一个tcp链接,无法实现上述的过程。

      • 对应在Go的代码上,以 github.com/gorilla/websocket 的WebSocket实现为例。其会在握手阶段将 http.ResponseWriter 断言为 http.Hijacker 接口并调用其中的 Hijack() 方法,拿到原始tcp链接对象并进行接管。而在使用HTTP/2时, http.ResponseWriter 无法断言为 http.Hijacker

        github.com/gorilla/websocket

        h, ok := w.(http.Hijacker)
        if !ok {
          return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
        }
        var brw *bufio.ReadWriter
        netConn, brw, err = h.Hijack()
        if err != nil {
          return u.returnError(w, r, http.StatusInternalServerError, err.Error())
        }

        http.Hijacker

        // The Hijacker interface is implemented by ResponseWriters that allow
        // an HTTP handler to take over the connection.
        //
        // The default ResponseWriter for HTTP/1.x connections supports
        // Hijacker, but HTTP/2 connections intentionally do not.
        // ResponseWriter wrappers may also not support Hijacker. Handlers
        // should always test for this ability at runtime.
        type Hijacker interface {
          // 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 should
          // not be used.
          Hijack() (net.Conn, *bufio.ReadWriter, error)
        }
    • 有一个 WebSocket over HTTP/2 的草案,不过并没有什么用,看样子这问题暂时无解。

  • 关于HTTP/2的Server Push,其主要用途是提前推送web资源以减少延时。无法像WebSocket一样作为实时的消息推送手段

    HTTP1.X、HTTP/2、websocket、http.Hijacker golang

    image.png


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Little Typer

The Little Typer

Daniel P. Friedman、David Thrane Christiansen、Duane Bibby、Robert Harper、Conor Mcbride / MIT Press / 2018-10-16 / GBP 30.00

An introduction to dependent types, demonstrating the most beautiful aspects, one step at a time. A program's type describes its behavior. Dependent types are a first-class part of a language, and are......一起来看看 《The Little Typer》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具