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