Source file src/net/http/http.go
1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:generate bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2 6 7 package http 8 9 import ( 10 "io" 11 "strconv" 12 "strings" 13 "time" 14 "unicode/utf8" 15 16 "golang.org/x/net/http/httpguts" 17 ) 18 19 // Protocols is a set of HTTP protocols. 20 // 21 // The supported protocols are: 22 // 23 // - HTTP1 is the HTTP/1.0 and HTTP/1.1 protocols. 24 // HTTP1 is supported on both unsecured TCP and secured TLS connections. 25 // 26 // - HTTP2 is the HTTP/2 protcol over a TLS connection. 27 type Protocols struct { 28 bits uint8 29 } 30 31 const ( 32 protoHTTP1 = 1 << iota 33 protoHTTP2 34 ) 35 36 // HTTP1 reports whether p includes HTTP/1. 37 func (p Protocols) HTTP1() bool { return p.bits&protoHTTP1 != 0 } 38 39 // SetHTTP1 adds or removes HTTP/1 from p. 40 func (p *Protocols) SetHTTP1(ok bool) { p.setBit(protoHTTP1, ok) } 41 42 // HTTP2 reports whether p includes HTTP/2. 43 func (p Protocols) HTTP2() bool { return p.bits&protoHTTP2 != 0 } 44 45 // SetHTTP2 adds or removes HTTP/2 from p. 46 func (p *Protocols) SetHTTP2(ok bool) { p.setBit(protoHTTP2, ok) } 47 48 func (p *Protocols) setBit(bit uint8, ok bool) { 49 if ok { 50 p.bits |= bit 51 } else { 52 p.bits &^= bit 53 } 54 } 55 56 func (p Protocols) String() string { 57 var s []string 58 if p.HTTP1() { 59 s = append(s, "HTTP1") 60 } 61 if p.HTTP2() { 62 s = append(s, "HTTP2") 63 } 64 return "{" + strings.Join(s, ",") + "}" 65 } 66 67 // incomparable is a zero-width, non-comparable type. Adding it to a struct 68 // makes that struct also non-comparable, and generally doesn't add 69 // any size (as long as it's first). 70 type incomparable [0]func() 71 72 // maxInt64 is the effective "infinite" value for the Server and 73 // Transport's byte-limiting readers. 74 const maxInt64 = 1<<63 - 1 75 76 // aLongTimeAgo is a non-zero time, far in the past, used for 77 // immediate cancellation of network operations. 78 var aLongTimeAgo = time.Unix(1, 0) 79 80 // omitBundledHTTP2 is set by omithttp2.go when the nethttpomithttp2 81 // build tag is set. That means h2_bundle.go isn't compiled in and we 82 // shouldn't try to use it. 83 var omitBundledHTTP2 bool 84 85 // TODO(bradfitz): move common stuff here. The other files have accumulated 86 // generic http stuff in random places. 87 88 // contextKey is a value for use with context.WithValue. It's used as 89 // a pointer so it fits in an interface{} without allocation. 90 type contextKey struct { 91 name string 92 } 93 94 func (k *contextKey) String() string { return "net/http context value " + k.name } 95 96 // Given a string of the form "host", "host:port", or "[ipv6::address]:port", 97 // return true if the string includes a port. 98 func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") } 99 100 // removeEmptyPort strips the empty port in ":port" to "" 101 // as mandated by RFC 3986 Section 6.2.3. 102 func removeEmptyPort(host string) string { 103 if hasPort(host) { 104 return strings.TrimSuffix(host, ":") 105 } 106 return host 107 } 108 109 func isNotToken(r rune) bool { 110 return !httpguts.IsTokenRune(r) 111 } 112 113 // stringContainsCTLByte reports whether s contains any ASCII control character. 114 func stringContainsCTLByte(s string) bool { 115 for i := 0; i < len(s); i++ { 116 b := s[i] 117 if b < ' ' || b == 0x7f { 118 return true 119 } 120 } 121 return false 122 } 123 124 func hexEscapeNonASCII(s string) string { 125 newLen := 0 126 for i := 0; i < len(s); i++ { 127 if s[i] >= utf8.RuneSelf { 128 newLen += 3 129 } else { 130 newLen++ 131 } 132 } 133 if newLen == len(s) { 134 return s 135 } 136 b := make([]byte, 0, newLen) 137 var pos int 138 for i := 0; i < len(s); i++ { 139 if s[i] >= utf8.RuneSelf { 140 if pos < i { 141 b = append(b, s[pos:i]...) 142 } 143 b = append(b, '%') 144 b = strconv.AppendInt(b, int64(s[i]), 16) 145 pos = i + 1 146 } 147 } 148 if pos < len(s) { 149 b = append(b, s[pos:]...) 150 } 151 return string(b) 152 } 153 154 // NoBody is an [io.ReadCloser] with no bytes. Read always returns EOF 155 // and Close always returns nil. It can be used in an outgoing client 156 // request to explicitly signal that a request has zero bytes. 157 // An alternative, however, is to simply set [Request.Body] to nil. 158 var NoBody = noBody{} 159 160 type noBody struct{} 161 162 func (noBody) Read([]byte) (int, error) { return 0, io.EOF } 163 func (noBody) Close() error { return nil } 164 func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil } 165 166 var ( 167 // verify that an io.Copy from NoBody won't require a buffer: 168 _ io.WriterTo = NoBody 169 _ io.ReadCloser = NoBody 170 ) 171 172 // PushOptions describes options for [Pusher.Push]. 173 type PushOptions struct { 174 // Method specifies the HTTP method for the promised request. 175 // If set, it must be "GET" or "HEAD". Empty means "GET". 176 Method string 177 178 // Header specifies additional promised request headers. This cannot 179 // include HTTP/2 pseudo header fields like ":path" and ":scheme", 180 // which will be added automatically. 181 Header Header 182 } 183 184 // Pusher is the interface implemented by ResponseWriters that support 185 // HTTP/2 server push. For more background, see 186 // https://tools.ietf.org/html/rfc7540#section-8.2. 187 type Pusher interface { 188 // Push initiates an HTTP/2 server push. This constructs a synthetic 189 // request using the given target and options, serializes that request 190 // into a PUSH_PROMISE frame, then dispatches that request using the 191 // server's request handler. If opts is nil, default options are used. 192 // 193 // The target must either be an absolute path (like "/path") or an absolute 194 // URL that contains a valid host and the same scheme as the parent request. 195 // If the target is a path, it will inherit the scheme and host of the 196 // parent request. 197 // 198 // The HTTP/2 spec disallows recursive pushes and cross-authority pushes. 199 // Push may or may not detect these invalid pushes; however, invalid 200 // pushes will be detected and canceled by conforming clients. 201 // 202 // Handlers that wish to push URL X should call Push before sending any 203 // data that may trigger a request for URL X. This avoids a race where the 204 // client issues requests for X before receiving the PUSH_PROMISE for X. 205 // 206 // Push will run in a separate goroutine making the order of arrival 207 // non-deterministic. Any required synchronization needs to be implemented 208 // by the caller. 209 // 210 // Push returns ErrNotSupported if the client has disabled push or if push 211 // is not supported on the underlying connection. 212 Push(target string, opts *PushOptions) error 213 } 214 215 // HTTP2Config defines HTTP/2 configuration parameters common to 216 // both [Transport] and [Server]. 217 type HTTP2Config struct { 218 // MaxConcurrentStreams optionally specifies the number of 219 // concurrent streams that a peer may have open at a time. 220 // If zero, MaxConcurrentStreams defaults to at least 100. 221 MaxConcurrentStreams int 222 223 // MaxDecoderHeaderTableSize optionally specifies an upper limit for the 224 // size of the header compression table used for decoding headers sent 225 // by the peer. 226 // A valid value is less than 4MiB. 227 // If zero or invalid, a default value is used. 228 MaxDecoderHeaderTableSize int 229 230 // MaxEncoderHeaderTableSize optionally specifies an upper limit for the 231 // header compression table used for sending headers to the peer. 232 // A valid value is less than 4MiB. 233 // If zero or invalid, a default value is used. 234 MaxEncoderHeaderTableSize int 235 236 // MaxReadFrameSize optionally specifies the largest frame 237 // this endpoint is willing to read. 238 // A valid value is between 16KiB and 16MiB, inclusive. 239 // If zero or invalid, a default value is used. 240 MaxReadFrameSize int 241 242 // MaxReceiveBufferPerConnection is the maximum size of the 243 // flow control window for data received on a connection. 244 // A valid value is at least 64KiB and less than 4MiB. 245 // If invalid, a default value is used. 246 MaxReceiveBufferPerConnection int 247 248 // MaxReceiveBufferPerStream is the maximum size of 249 // the flow control window for data received on a stream (request). 250 // A valid value is less than 4MiB. 251 // If zero or invalid, a default value is used. 252 MaxReceiveBufferPerStream int 253 254 // SendPingTimeout is the timeout after which a health check using a ping 255 // frame will be carried out if no frame is received on a connection. 256 // If zero, no health check is performed. 257 SendPingTimeout time.Duration 258 259 // PingTimeout is the timeout after which a connection will be closed 260 // if a response to a ping is not received. 261 // If zero, a default of 15 seconds is used. 262 PingTimeout time.Duration 263 264 // WriteByteTimeout is the timeout after which a connection will be 265 // closed if no data can be written to it. The timeout begins when data is 266 // available to write, and is extended whenever any bytes are written. 267 WriteByteTimeout time.Duration 268 269 // PermitProhibitedCipherSuites, if true, permits the use of 270 // cipher suites prohibited by the HTTP/2 spec. 271 PermitProhibitedCipherSuites bool 272 273 // CountError, if non-nil, is called on HTTP/2 errors. 274 // It is intended to increment a metric for monitoring. 275 // The errType contains only lowercase letters, digits, and underscores 276 // (a-z, 0-9, _). 277 CountError func(errType string) 278 } 279