1
2
3
4
5
6
type Response struct {
	// As of Go 1.12, the Body will also implement io.Writer
	// on a successful "101 Switching Protocols" response,
	// as used by WebSockets and HTTP/2's "h2c" mode.
	Body io.ReadCloser
}

如果是 Switching Protocols,返回的 Body 是可写的:

1
2
3
4
5
6
7
// readResponse reads an HTTP response (or two, in the case of "Expect:
// 100-continue") from the server. It returns the final non-100 one.
// trace is optional.
func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTrace) (resp *Response, err error) {
	if resp.isProtocolSwitch() {
		resp.Body = newReadWriteCloserBody(pc.br, pc.conn)
	}

上述判断需满足的条件

  1. 状态码为 Switching Protocols(101);
  2. Connection 头部包含 Upgrade
  3. 包含 Upgrade 头部。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// isProtocolSwitchResponse reports whether the response code and
// response header indicate a successful protocol upgrade response.
func isProtocolSwitchResponse(code int, h Header) bool {
	return code == StatusSwitchingProtocols && isProtocolSwitchHeader(h)
}


// isProtocolSwitchHeader reports whether the request or response header
// is for a protocol switch.
func isProtocolSwitchHeader(h Header) bool {
	return h.Get("Upgrade") != "" &&
		httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade")
}

所以类似需要 Upgrade 的请求不必再手动构造 Request、ReadResponse 了。

#Go #HTTP

桃子的碎碎念 桃子 编辑