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