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