Update apimachinery

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
This commit is contained in:
Alex Ellis (OpenFaaS Ltd) 2022-10-03 16:46:59 +01:00
parent 95792f8d58
commit 7c118225b2
18 changed files with 277 additions and 165 deletions

4
go.mod
View File

@ -25,7 +25,7 @@ require (
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
github.com/vishvananda/netns v0.0.0-20220913150850-18c4f4234207 github.com/vishvananda/netns v0.0.0-20220913150850-18c4f4234207
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
k8s.io/apimachinery v0.24.3 k8s.io/apimachinery v0.25.2
) )
require ( require (
@ -69,7 +69,7 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.opencensus.io v0.23.0 // indirect go.opencensus.io v0.23.0 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect

1
go.sum
View File

@ -1301,6 +1301,7 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

3
vendor/golang.org/x/net/AUTHORS generated vendored
View File

@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

View File

@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

View File

@ -173,13 +173,15 @@ func tokenEqual(t1, t2 string) bool {
// isLWS reports whether b is linear white space, according // isLWS reports whether b is linear white space, according
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 // to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
// LWS = [CRLF] 1*( SP | HT ) //
// LWS = [CRLF] 1*( SP | HT )
func isLWS(b byte) bool { return b == ' ' || b == '\t' } func isLWS(b byte) bool { return b == ' ' || b == '\t' }
// isCTL reports whether b is a control byte, according // isCTL reports whether b is a control byte, according
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 // to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
// CTL = <any US-ASCII control character //
// (octets 0 - 31) and DEL (127)> // CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
func isCTL(b byte) bool { func isCTL(b byte) bool {
const del = 0x7f // a CTL const del = 0x7f // a CTL
return b < ' ' || b == del return b < ' ' || b == del
@ -189,12 +191,13 @@ func isCTL(b byte) bool {
// HTTP/2 imposes the additional restriction that uppercase ASCII // HTTP/2 imposes the additional restriction that uppercase ASCII
// letters are not allowed. // letters are not allowed.
// //
// RFC 7230 says: // RFC 7230 says:
// header-field = field-name ":" OWS field-value OWS //
// field-name = token // header-field = field-name ":" OWS field-value OWS
// token = 1*tchar // field-name = token
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / // token = 1*tchar
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA // tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
func ValidHeaderFieldName(v string) bool { func ValidHeaderFieldName(v string) bool {
if len(v) == 0 { if len(v) == 0 {
return false return false
@ -267,27 +270,28 @@ var validHostByte = [256]bool{
// ValidHeaderFieldValue reports whether v is a valid "field-value" according to // ValidHeaderFieldValue reports whether v is a valid "field-value" according to
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 : // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
// //
// message-header = field-name ":" [ field-value ] // message-header = field-name ":" [ field-value ]
// field-value = *( field-content | LWS ) // field-value = *( field-content | LWS )
// field-content = <the OCTETs making up the field-value // field-content = <the OCTETs making up the field-value
// and consisting of either *TEXT or combinations // and consisting of either *TEXT or combinations
// of token, separators, and quoted-string> // of token, separators, and quoted-string>
// //
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 : // http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
// //
// TEXT = <any OCTET except CTLs, // TEXT = <any OCTET except CTLs,
// but including LWS> // but including LWS>
// LWS = [CRLF] 1*( SP | HT ) // LWS = [CRLF] 1*( SP | HT )
// CTL = <any US-ASCII control character // CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)> // (octets 0 - 31) and DEL (127)>
// //
// RFC 7230 says: // RFC 7230 says:
// field-value = *( field-content / obs-fold ) //
// obj-fold = N/A to http2, and deprecated // field-value = *( field-content / obs-fold )
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] // obj-fold = N/A to http2, and deprecated
// field-vchar = VCHAR / obs-text // field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// obs-text = %x80-FF // field-vchar = VCHAR / obs-text
// VCHAR = "any visible [USASCII] character" // obs-text = %x80-FF
// VCHAR = "any visible [USASCII] character"
// //
// http2 further says: "Similarly, HTTP/2 allows header field values // http2 further says: "Similarly, HTTP/2 allows header field values
// that are not valid. While most of the values that can be encoded // that are not valid. While most of the values that can be encoded

View File

@ -139,7 +139,6 @@ func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *d
func (c *dialCall) dial(ctx context.Context, addr string) { func (c *dialCall) dial(ctx context.Context, addr string) {
const singleUse = false // shared conn const singleUse = false // shared conn
c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse) c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
close(c.done)
c.p.mu.Lock() c.p.mu.Lock()
delete(c.p.dialing, addr) delete(c.p.dialing, addr)
@ -147,6 +146,8 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
c.p.addConnLocked(addr, c.res) c.p.addConnLocked(addr, c.res)
} }
c.p.mu.Unlock() c.p.mu.Unlock()
close(c.done)
} }
// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't // addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't

View File

@ -136,7 +136,7 @@ func (e headerFieldNameError) Error() string {
type headerFieldValueError string type headerFieldValueError string
func (e headerFieldValueError) Error() string { func (e headerFieldValueError) Error() string {
return fmt.Sprintf("invalid header field value %q", string(e)) return fmt.Sprintf("invalid header field value for %q", string(e))
} }
var ( var (

View File

@ -1532,7 +1532,8 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
} }
if !httpguts.ValidHeaderFieldValue(hf.Value) { if !httpguts.ValidHeaderFieldValue(hf.Value) {
invalid = headerFieldValueError(hf.Value) // Don't include the value in the error, because it may be sensitive.
invalid = headerFieldValueError(hf.Name)
} }
isPseudo := strings.HasPrefix(hf.Name, ":") isPseudo := strings.HasPrefix(hf.Name, ":")
if isPseudo { if isPseudo {

View File

@ -169,25 +169,50 @@ func buildRootHuffmanNode() {
// AppendHuffmanString appends s, as encoded in Huffman codes, to dst // AppendHuffmanString appends s, as encoded in Huffman codes, to dst
// and returns the extended buffer. // and returns the extended buffer.
func AppendHuffmanString(dst []byte, s string) []byte { func AppendHuffmanString(dst []byte, s string) []byte {
rembits := uint8(8) // This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)
// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.
var (
x uint64 // buffer
n uint // number valid of bits present in x
)
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
if rembits == 8 { c := s[i]
dst = append(dst, 0) n += uint(huffmanCodeLen[c])
x <<= huffmanCodeLen[c] % 64
x |= uint64(huffmanCodes[c])
if n >= 32 {
n %= 32 // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift
y := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32
dst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
} }
dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
} }
// Add padding bits if necessary
if rembits < 8 { if over := n % 8; over > 0 {
// special EOS symbol const (
code := uint32(0x3fffffff) eosCode = 0x3fffffff
nbits := uint8(30) eosNBits = 30
eosPadByte = eosCode >> (eosNBits - 8)
t := uint8(code >> (nbits - rembits)) )
dst[len(dst)-1] |= t pad := 8 - over
x = (x << pad) | (eosPadByte >> over)
n += pad // 8 now divides into n exactly
} }
// n in (0, 8, 16, 24, 32)
return dst switch n / 8 {
case 0:
return dst
case 1:
return append(dst, byte(x))
case 2:
y := uint16(x)
return append(dst, byte(y>>8), byte(y))
case 3:
y := uint16(x >> 8)
return append(dst, byte(y>>8), byte(y), byte(x))
}
// case 4:
y := uint32(x)
return append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
} }
// HuffmanEncodeLength returns the number of bytes required to encode // HuffmanEncodeLength returns the number of bytes required to encode
@ -199,35 +224,3 @@ func HuffmanEncodeLength(s string) uint64 {
} }
return (n + 7) / 8 return (n + 7) / 8
} }
// appendByteToHuffmanCode appends Huffman code for c to dst and
// returns the extended buffer and the remaining bits in the last
// element. The appending is not byte aligned and the remaining bits
// in the last element of dst is given in rembits.
func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
code := huffmanCodes[c]
nbits := huffmanCodeLen[c]
for {
if rembits > nbits {
t := uint8(code << (rembits - nbits))
dst[len(dst)-1] |= t
rembits -= nbits
break
}
t := uint8(code >> (nbits - rembits))
dst[len(dst)-1] |= t
nbits -= rembits
rembits = 8
if nbits == 0 {
break
}
dst = append(dst, 0)
}
return dst, rembits
}

View File

@ -13,7 +13,6 @@
// See https://http2.github.io/ for more information on HTTP/2. // See https://http2.github.io/ for more information on HTTP/2.
// //
// See https://http2.golang.org/ for a test server running this code. // See https://http2.golang.org/ for a test server running this code.
//
package http2 // import "golang.org/x/net/http2" package http2 // import "golang.org/x/net/http2"
import ( import (
@ -176,10 +175,11 @@ func (s SettingID) String() string {
// name (key). See httpguts.ValidHeaderName for the base rules. // name (key). See httpguts.ValidHeaderName for the base rules.
// //
// Further, http2 says: // Further, http2 says:
// "Just as in HTTP/1.x, header field names are strings of ASCII //
// characters that are compared in a case-insensitive // "Just as in HTTP/1.x, header field names are strings of ASCII
// fashion. However, header field names MUST be converted to // characters that are compared in a case-insensitive
// lowercase prior to their encoding in HTTP/2. " // fashion. However, header field names MUST be converted to
// lowercase prior to their encoding in HTTP/2. "
func validWireHeaderFieldName(v string) bool { func validWireHeaderFieldName(v string) bool {
if len(v) == 0 { if len(v) == 0 {
return false return false
@ -365,8 +365,8 @@ func (s *sorter) SortStrings(ss []string) {
// validPseudoPath reports whether v is a valid :path pseudo-header // validPseudoPath reports whether v is a valid :path pseudo-header
// value. It must be either: // value. It must be either:
// //
// *) a non-empty string starting with '/' // - a non-empty string starting with '/'
// *) the string '*', for OPTIONS requests. // - the string '*', for OPTIONS requests.
// //
// For now this is only used a quick check for deciding when to clean // For now this is only used a quick check for deciding when to clean
// up Opaque URLs before sending requests from the Transport. // up Opaque URLs before sending requests from the Transport.

View File

@ -315,6 +315,20 @@ type ServeConnOpts struct {
// requests. If nil, BaseConfig.Handler is used. If BaseConfig // requests. If nil, BaseConfig.Handler is used. If BaseConfig
// or BaseConfig.Handler is nil, http.DefaultServeMux is used. // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
Handler http.Handler Handler http.Handler
// UpgradeRequest is an initial request received on a connection
// undergoing an h2c upgrade. The request body must have been
// completely read from the connection before calling ServeConn,
// and the 101 Switching Protocols response written.
UpgradeRequest *http.Request
// Settings is the decoded contents of the HTTP2-Settings header
// in an h2c upgrade request.
Settings []byte
// SawClientPreface is set if the HTTP/2 connection preface
// has already been read from the connection.
SawClientPreface bool
} }
func (o *ServeConnOpts) context() context.Context { func (o *ServeConnOpts) context() context.Context {
@ -383,6 +397,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
headerTableSize: initialHeaderTableSize, headerTableSize: initialHeaderTableSize,
serveG: newGoroutineLock(), serveG: newGoroutineLock(),
pushEnabled: true, pushEnabled: true,
sawClientPreface: opts.SawClientPreface,
} }
s.state.registerConn(sc) s.state.registerConn(sc)
@ -400,7 +415,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
if s.NewWriteScheduler != nil { if s.NewWriteScheduler != nil {
sc.writeSched = s.NewWriteScheduler() sc.writeSched = s.NewWriteScheduler()
} else { } else {
sc.writeSched = NewRandomWriteScheduler() sc.writeSched = NewPriorityWriteScheduler(nil)
} }
// These start at the RFC-specified defaults. If there is a higher // These start at the RFC-specified defaults. If there is a higher
@ -465,9 +480,27 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
} }
} }
if opts.Settings != nil {
fr := &SettingsFrame{
FrameHeader: FrameHeader{valid: true},
p: opts.Settings,
}
if err := fr.ForeachSetting(sc.processSetting); err != nil {
sc.rejectConn(ErrCodeProtocol, "invalid settings")
return
}
opts.Settings = nil
}
if hook := testHookGetServerConn; hook != nil { if hook := testHookGetServerConn; hook != nil {
hook(sc) hook(sc)
} }
if opts.UpgradeRequest != nil {
sc.upgradeRequest(opts.UpgradeRequest)
opts.UpgradeRequest = nil
}
sc.serve() sc.serve()
} }
@ -512,6 +545,7 @@ type serverConn struct {
// Everything following is owned by the serve loop; use serveG.check(): // Everything following is owned by the serve loop; use serveG.check():
serveG goroutineLock // used to verify funcs are on serve() serveG goroutineLock // used to verify funcs are on serve()
pushEnabled bool pushEnabled bool
sawClientPreface bool // preface has already been read, used in h2c upgrade
sawFirstSettings bool // got the initial SETTINGS frame after the preface sawFirstSettings bool // got the initial SETTINGS frame after the preface
needToSendSettingsAck bool needToSendSettingsAck bool
unackedSettings int // how many SETTINGS have we sent without ACKs? unackedSettings int // how many SETTINGS have we sent without ACKs?
@ -974,6 +1008,9 @@ var errPrefaceTimeout = errors.New("timeout waiting for client preface")
// returns errPrefaceTimeout on timeout, or an error if the greeting // returns errPrefaceTimeout on timeout, or an error if the greeting
// is invalid. // is invalid.
func (sc *serverConn) readPreface() error { func (sc *serverConn) readPreface() error {
if sc.sawClientPreface {
return nil
}
errc := make(chan error, 1) errc := make(chan error, 1)
go func() { go func() {
// Read the client preface // Read the client preface
@ -1915,6 +1952,26 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
return nil return nil
} }
func (sc *serverConn) upgradeRequest(req *http.Request) {
sc.serveG.check()
id := uint32(1)
sc.maxClientStreamID = id
st := sc.newStream(id, 0, stateHalfClosedRemote)
st.reqTrailer = req.Trailer
if st.reqTrailer != nil {
st.trailer = make(http.Header)
}
rw := sc.newResponseWriter(st, req)
// Disable any read deadline set by the net/http package
// prior to the upgrade.
if sc.hs.ReadTimeout != 0 {
sc.conn.SetReadDeadline(time.Time{})
}
go sc.runHandler(rw, req, sc.handler.ServeHTTP)
}
func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
sc := st.sc sc := st.sc
sc.serveG.check() sc.serveG.check()
@ -2145,6 +2202,11 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
} }
req = req.WithContext(st.ctx) req = req.WithContext(st.ctx)
rw := sc.newResponseWriter(st, req)
return rw, req, nil
}
func (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *responseWriter {
rws := responseWriterStatePool.Get().(*responseWriterState) rws := responseWriterStatePool.Get().(*responseWriterState)
bwSave := rws.bw bwSave := rws.bw
*rws = responseWriterState{} // zero all the fields *rws = responseWriterState{} // zero all the fields
@ -2153,10 +2215,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
rws.bw.Reset(chunkWriter{rws}) rws.bw.Reset(chunkWriter{rws})
rws.stream = st rws.stream = st
rws.req = req rws.req = req
rws.body = body return &responseWriter{rws: rws}
rw := &responseWriter{rws: rws}
return rw, req, nil
} }
// Run on its own goroutine. // Run on its own goroutine.
@ -2316,17 +2375,18 @@ type requestBody struct {
_ incomparable _ incomparable
stream *stream stream *stream
conn *serverConn conn *serverConn
closed bool // for use by Close only closeOnce sync.Once // for use by Close only
sawEOF bool // for use by Read only sawEOF bool // for use by Read only
pipe *pipe // non-nil if we have a HTTP entity message body pipe *pipe // non-nil if we have a HTTP entity message body
needsContinue bool // need to send a 100-continue needsContinue bool // need to send a 100-continue
} }
func (b *requestBody) Close() error { func (b *requestBody) Close() error {
if b.pipe != nil && !b.closed { b.closeOnce.Do(func() {
b.pipe.BreakWithError(errClosedBody) if b.pipe != nil {
} b.pipe.BreakWithError(errClosedBody)
b.closed = true }
})
return nil return nil
} }
@ -2370,7 +2430,6 @@ type responseWriterState struct {
// immutable within a request: // immutable within a request:
stream *stream stream *stream
req *http.Request req *http.Request
body *requestBody // to close at end of request, if DATA frames didn't
conn *serverConn conn *serverConn
// TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
@ -2546,8 +2605,9 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
// prior to the headers being written. If the set of trailers is fixed // prior to the headers being written. If the set of trailers is fixed
// or known before the header is written, the normal Go trailers mechanism // or known before the header is written, the normal Go trailers mechanism
// is preferred: // is preferred:
// https://golang.org/pkg/net/http/#ResponseWriter //
// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers // https://golang.org/pkg/net/http/#ResponseWriter
// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
const TrailerPrefix = "Trailer:" const TrailerPrefix = "Trailer:"
// promoteUndeclaredTrailers permits http.Handlers to set trailers // promoteUndeclaredTrailers permits http.Handlers to set trailers
@ -2643,8 +2703,7 @@ func checkWriteHeaderCode(code int) {
// Issue 22880: require valid WriteHeader status codes. // Issue 22880: require valid WriteHeader status codes.
// For now we only enforce that it's three digits. // For now we only enforce that it's three digits.
// In the future we might block things over 599 (600 and above aren't defined // In the future we might block things over 599 (600 and above aren't defined
// at http://httpwg.org/specs/rfc7231.html#status.codes) // at http://httpwg.org/specs/rfc7231.html#status.codes).
// and we might block under 200 (once we have more mature 1xx support).
// But for now any three digits. // But for now any three digits.
// //
// We used to send "HTTP/1.1 000 0" on the wire in responses but there's // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
@ -2665,13 +2724,41 @@ func (w *responseWriter) WriteHeader(code int) {
} }
func (rws *responseWriterState) writeHeader(code int) { func (rws *responseWriterState) writeHeader(code int) {
if !rws.wroteHeader { if rws.wroteHeader {
checkWriteHeaderCode(code) return
rws.wroteHeader = true }
rws.status = code
if len(rws.handlerHeader) > 0 { checkWriteHeaderCode(code)
rws.snapHeader = cloneHeader(rws.handlerHeader)
// Handle informational headers
if code >= 100 && code <= 199 {
// Per RFC 8297 we must not clear the current header map
h := rws.handlerHeader
_, cl := h["Content-Length"]
_, te := h["Transfer-Encoding"]
if cl || te {
h = h.Clone()
h.Del("Content-Length")
h.Del("Transfer-Encoding")
} }
if rws.conn.writeHeaders(rws.stream, &writeResHeaders{
streamID: rws.stream.id,
httpResCode: code,
h: h,
endStream: rws.handlerDone && !rws.hasTrailers(),
}) != nil {
rws.dirty = true
}
return
}
rws.wroteHeader = true
rws.status = code
if len(rws.handlerHeader) > 0 {
rws.snapHeader = cloneHeader(rws.handlerHeader)
} }
} }

View File

@ -16,7 +16,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"math" "math"
mathrand "math/rand" mathrand "math/rand"
@ -501,12 +500,14 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
if req, err = shouldRetryRequest(req, err); err == nil { if req, err = shouldRetryRequest(req, err); err == nil {
// After the first retry, do exponential backoff with 10% jitter. // After the first retry, do exponential backoff with 10% jitter.
if retry == 0 { if retry == 0 {
t.vlogf("RoundTrip retrying after failure: %v", err)
continue continue
} }
backoff := float64(uint(1) << (uint(retry) - 1)) backoff := float64(uint(1) << (uint(retry) - 1))
backoff += backoff * (0.1 * mathrand.Float64()) backoff += backoff * (0.1 * mathrand.Float64())
select { select {
case <-time.After(time.Second * time.Duration(backoff)): case <-time.After(time.Second * time.Duration(backoff)):
t.vlogf("RoundTrip retrying after failure: %v", err)
continue continue
case <-req.Context().Done(): case <-req.Context().Done():
err = req.Context().Err() err = req.Context().Err()
@ -732,10 +733,13 @@ func (cc *ClientConn) healthCheck() {
// trigger the healthCheck again if there is no frame received. // trigger the healthCheck again if there is no frame received.
ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
defer cancel() defer cancel()
cc.vlogf("http2: Transport sending health check")
err := cc.Ping(ctx) err := cc.Ping(ctx)
if err != nil { if err != nil {
cc.vlogf("http2: Transport health check failure: %v", err)
cc.closeForLostPing() cc.closeForLostPing()
return } else {
cc.vlogf("http2: Transport health check success")
} }
} }
@ -1765,7 +1769,8 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
} }
for _, v := range vv { for _, v := range vv {
if !httpguts.ValidHeaderFieldValue(v) { if !httpguts.ValidHeaderFieldValue(v) {
return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k) // Don't include the value in the error, because it may be sensitive.
return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
} }
} }
} }
@ -2898,7 +2903,12 @@ func (t *Transport) logf(format string, args ...interface{}) {
log.Printf(format, args...) log.Printf(format, args...)
} }
var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil)) var noBody io.ReadCloser = noBodyReader{}
type noBodyReader struct{}
func (noBodyReader) Close() error { return nil }
func (noBodyReader) Read([]byte) (int, error) { return 0, io.EOF }
type missingBody struct{} type missingBody struct{}

View File

@ -383,16 +383,15 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit
func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
var n *priorityNode var n *priorityNode
if id := wr.StreamID(); id == 0 { if wr.isControl() {
n = &ws.root n = &ws.root
} else { } else {
id := wr.StreamID()
n = ws.nodes[id] n = ws.nodes[id]
if n == nil { if n == nil {
// id is an idle or closed stream. wr should not be a HEADERS or // id is an idle or closed stream. wr should not be a HEADERS or
// DATA frame. However, wr can be a RST_STREAM. In this case, we // DATA frame. In other case, we push wr onto the root, rather
// push wr onto the root, rather than creating a new priorityNode, // than creating a new priorityNode.
// since RST_STREAM is tiny and the stream's priority is unknown
// anyway. See issue #17919.
if wr.DataSize() > 0 { if wr.DataSize() > 0 {
panic("add DATA on non-open stream") panic("add DATA on non-open stream")
} }

View File

@ -17,23 +17,23 @@ package idna
// //
// The per-rune values have the following format: // The per-rune values have the following format:
// //
// if mapped { // if mapped {
// if inlinedXOR { // if inlinedXOR {
// 15..13 inline XOR marker // 15..13 inline XOR marker
// 12..11 unused // 12..11 unused
// 10..3 inline XOR mask // 10..3 inline XOR mask
// } else { // } else {
// 15..3 index into xor or mapping table // 15..3 index into xor or mapping table
// } // }
// } else { // } else {
// 15..14 unused // 15..14 unused
// 13 mayNeedNorm // 13 mayNeedNorm
// 12..11 attributes // 12..11 attributes
// 10..8 joining type // 10..8 joining type
// 7..3 category type // 7..3 category type
// } // }
// 2 use xor pattern // 2 use xor pattern
// 1..0 mapped category // 1..0 mapped category
// //
// See the definitions below for a more detailed description of the various // See the definitions below for a more detailed description of the various
// bits. // bits.

View File

@ -30,8 +30,11 @@ option go_package = "k8s.io/apimachinery/pkg/api/resource";
// //
// The serialization format is: // The serialization format is:
// //
// ```
// <quantity> ::= <signedNumber><suffix> // <quantity> ::= <signedNumber><suffix>
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.) //
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
//
// <digit> ::= 0 | 1 | ... | 9 // <digit> ::= 0 | 1 | ... | 9
// <digits> ::= <digit> | <digit><digits> // <digits> ::= <digit> | <digit><digits>
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits> // <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
@ -39,10 +42,15 @@ option go_package = "k8s.io/apimachinery/pkg/api/resource";
// <signedNumber> ::= <number> | <sign><number> // <signedNumber> ::= <number> | <sign><number>
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI> // <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei // <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html) //
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
//
// <decimalSI> ::= m | "" | k | M | G | T | P | E // <decimalSI> ::= m | "" | k | M | G | T | P | E
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) //
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
//
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber> // <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
// ```
// //
// No matter which of the three exponent forms is used, no quantity may represent // No matter which of the three exponent forms is used, no quantity may represent
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal // a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
@ -56,14 +64,17 @@ option go_package = "k8s.io/apimachinery/pkg/api/resource";
// Before serializing, Quantity will be put in "canonical form". // Before serializing, Quantity will be put in "canonical form".
// This means that Exponent/suffix will be adjusted up or down (with a // This means that Exponent/suffix will be adjusted up or down (with a
// corresponding increase or decrease in Mantissa) such that: // corresponding increase or decrease in Mantissa) such that:
// a. No precision is lost //
// b. No fractional digits will be emitted // - No precision is lost
// c. The exponent (or suffix) is as large as possible. // - No fractional digits will be emitted
// - The exponent (or suffix) is as large as possible.
//
// The sign will be omitted unless the number is negative. // The sign will be omitted unless the number is negative.
// //
// Examples: // Examples:
// 1.5 will be serialized as "1500m" //
// 1.5Gi will be serialized as "1536Mi" // - 1.5 will be serialized as "1500m"
// - 1.5Gi will be serialized as "1536Mi"
// //
// Note that the quantity will NEVER be internally represented by a // Note that the quantity will NEVER be internally represented by a
// floating point number. That is the whole point of this exercise. // floating point number. That is the whole point of this exercise.

View File

@ -34,8 +34,11 @@ import (
// //
// The serialization format is: // The serialization format is:
// //
// ```
// <quantity> ::= <signedNumber><suffix> // <quantity> ::= <signedNumber><suffix>
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.) //
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
//
// <digit> ::= 0 | 1 | ... | 9 // <digit> ::= 0 | 1 | ... | 9
// <digits> ::= <digit> | <digit><digits> // <digits> ::= <digit> | <digit><digits>
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits> // <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
@ -43,10 +46,15 @@ import (
// <signedNumber> ::= <number> | <sign><number> // <signedNumber> ::= <number> | <sign><number>
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI> // <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei // <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html) //
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
//
// <decimalSI> ::= m | "" | k | M | G | T | P | E // <decimalSI> ::= m | "" | k | M | G | T | P | E
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) //
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
//
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber> // <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
// ```
// //
// No matter which of the three exponent forms is used, no quantity may represent // No matter which of the three exponent forms is used, no quantity may represent
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal // a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
@ -60,14 +68,17 @@ import (
// Before serializing, Quantity will be put in "canonical form". // Before serializing, Quantity will be put in "canonical form".
// This means that Exponent/suffix will be adjusted up or down (with a // This means that Exponent/suffix will be adjusted up or down (with a
// corresponding increase or decrease in Mantissa) such that: // corresponding increase or decrease in Mantissa) such that:
// a. No precision is lost //
// b. No fractional digits will be emitted // - No precision is lost
// c. The exponent (or suffix) is as large as possible. // - No fractional digits will be emitted
// - The exponent (or suffix) is as large as possible.
//
// The sign will be omitted unless the number is negative. // The sign will be omitted unless the number is negative.
// //
// Examples: // Examples:
// 1.5 will be serialized as "1500m" //
// 1.5Gi will be serialized as "1536Mi" // - 1.5 will be serialized as "1500m"
// - 1.5Gi will be serialized as "1536Mi"
// //
// Note that the quantity will NEVER be internally represented by a // Note that the quantity will NEVER be internally represented by a
// floating point number. That is the whole point of this exercise. // floating point number. That is the whole point of this exercise.
@ -404,10 +415,10 @@ func (Quantity) OpenAPIV3OneOfTypes() []string { return []string{"string", "numb
// CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity). // CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity).
// //
// Note about BinarySI: // Note about BinarySI:
// * If q.Format is set to BinarySI and q.Amount represents a non-zero value between // - If q.Format is set to BinarySI and q.Amount represents a non-zero value between
// -1 and +1, it will be emitted as if q.Format were DecimalSI. // -1 and +1, it will be emitted as if q.Format were DecimalSI.
// * Otherwise, if q.Format is set to BinarySI, fractional parts of q.Amount will be // - Otherwise, if q.Format is set to BinarySI, fractional parts of q.Amount will be
// rounded up. (1.1i becomes 2i.) // rounded up. (1.1i becomes 2i.)
func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) { func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) {
if q.IsZero() { if q.IsZero() {
return zeroBytes, nil return zeroBytes, nil
@ -643,7 +654,7 @@ func (q Quantity) MarshalJSON() ([]byte, error) {
copy(out[1:], q.s) copy(out[1:], q.s)
return out, nil return out, nil
} }
result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes) result := make([]byte, int64QuantityExpectedBytes)
result[0] = '"' result[0] = '"'
number, suffix := q.CanonicalizeBytes(result[1:1]) number, suffix := q.CanonicalizeBytes(result[1:1])
// if the same slice was returned to us that we passed in, avoid another allocation by copying number into // if the same slice was returned to us that we passed in, avoid another allocation by copying number into

View File

@ -165,7 +165,7 @@ func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s
if exponent == 0 { if exponent == 0 {
return nil, true return nil, true
} }
result := make([]byte, 8, 8) result := make([]byte, 8)
result[0] = 'e' result[0] = 'e'
number := strconv.AppendInt(result[1:1], int64(exponent), 10) number := strconv.AppendInt(result[1:1], int64(exponent), 10)
if &result[1] == &number[0] { if &result[1] == &number[0] {

6
vendor/modules.txt generated vendored
View File

@ -321,7 +321,7 @@ go.opencensus.io/internal
go.opencensus.io/trace go.opencensus.io/trace
go.opencensus.io/trace/internal go.opencensus.io/trace/internal
go.opencensus.io/trace/tracestate go.opencensus.io/trace/tracestate
# golang.org/x/net v0.0.0-20220225172249-27dd8689420f # golang.org/x/net v0.0.0-20220722155237-a158d28d115b
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/net/context/ctxhttp golang.org/x/net/context/ctxhttp
golang.org/x/net/http/httpguts golang.org/x/net/http/httpguts
@ -435,6 +435,6 @@ gopkg.in/inf.v0
# gopkg.in/yaml.v2 v2.4.0 # gopkg.in/yaml.v2 v2.4.0
## explicit; go 1.15 ## explicit; go 1.15
gopkg.in/yaml.v2 gopkg.in/yaml.v2
# k8s.io/apimachinery v0.24.3 # k8s.io/apimachinery v0.25.2
## explicit; go 1.16 ## explicit; go 1.19
k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/api/resource