mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-31 16:13:45 +08:00 
			
		
		
		
	vendor: update buildkit to f238f1e
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
		
							
								
								
									
										46
									
								
								vendor/google.golang.org/grpc/internal/balancerload/load.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/google.golang.org/grpc/internal/balancerload/load.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * Copyright 2019 gRPC authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| // Package balancerload defines APIs to parse server loads in trailers. The | ||||
| // parsed loads are sent to balancers in DoneInfo. | ||||
| package balancerload | ||||
|  | ||||
| import ( | ||||
| 	"google.golang.org/grpc/metadata" | ||||
| ) | ||||
|  | ||||
| // Parser converts loads from metadata into a concrete type. | ||||
| type Parser interface { | ||||
| 	// Parse parses loads from metadata. | ||||
| 	Parse(md metadata.MD) interface{} | ||||
| } | ||||
|  | ||||
| var parser Parser | ||||
|  | ||||
| // SetParser sets the load parser. | ||||
| // | ||||
| // Not mutex-protected, should be called before any gRPC functions. | ||||
| func SetParser(lr Parser) { | ||||
| 	parser = lr | ||||
| } | ||||
|  | ||||
| // Parse calls parser.Read(). | ||||
| func Parse(md metadata.MD) interface{} { | ||||
| 	if parser == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return parser.Parse(md) | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -34,13 +34,9 @@ const ( | ||||
| type RequireHandshakeSetting int | ||||
|  | ||||
| const ( | ||||
| 	// RequireHandshakeHybrid (default, deprecated) indicates to not wait for | ||||
| 	// handshake before considering a connection ready, but wait before | ||||
| 	// considering successful. | ||||
| 	RequireHandshakeHybrid RequireHandshakeSetting = iota | ||||
| 	// RequireHandshakeOn (default after the 1.17 release) indicates to wait | ||||
| 	// for handshake before considering a connection ready/successful. | ||||
| 	RequireHandshakeOn | ||||
| 	// RequireHandshakeOn indicates to wait for handshake before considering a | ||||
| 	// connection ready/successful. | ||||
| 	RequireHandshakeOn RequireHandshakeSetting = iota | ||||
| 	// RequireHandshakeOff indicates to not wait for handshake before | ||||
| 	// considering a connection ready/successful. | ||||
| 	RequireHandshakeOff | ||||
| @@ -53,7 +49,7 @@ var ( | ||||
| 	// environment variable. | ||||
| 	// | ||||
| 	// Will be removed after the 1.18 release. | ||||
| 	RequireHandshake RequireHandshakeSetting | ||||
| 	RequireHandshake = RequireHandshakeOn | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| @@ -64,8 +60,5 @@ func init() { | ||||
| 		RequireHandshake = RequireHandshakeOn | ||||
| 	case "off": | ||||
| 		RequireHandshake = RequireHandshakeOff | ||||
| 	case "hybrid": | ||||
| 		// Will be removed after the 1.17 release. | ||||
| 		RequireHandshake = RequireHandshakeHybrid | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -22,18 +22,24 @@ package syscall | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"google.golang.org/grpc/grpclog" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.") | ||||
| var once sync.Once | ||||
|  | ||||
| func log() { | ||||
| 	once.Do(func() { | ||||
| 		grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.") | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // GetCPUTime returns the how much CPU time has passed since the start of this process. | ||||
| // It always returns 0 under non-linux or appengine environment. | ||||
| func GetCPUTime() int64 { | ||||
| 	log() | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| @@ -42,22 +48,26 @@ type Rusage struct{} | ||||
|  | ||||
| // GetRusage is a no-op function under non-linux or appengine environment. | ||||
| func GetRusage() (rusage *Rusage) { | ||||
| 	log() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // CPUTimeDiff returns the differences of user CPU time and system CPU time used | ||||
| // between two Rusage structs. It a no-op function for non-linux or appengine environment. | ||||
| func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { | ||||
| 	log() | ||||
| 	return 0, 0 | ||||
| } | ||||
|  | ||||
| // SetTCPUserTimeout is a no-op function under non-linux or appengine environments | ||||
| func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { | ||||
| 	log() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GetTCPUserTimeout is a no-op function under non-linux or appengine environments | ||||
| // a negative return value indicates the operation is not supported | ||||
| func GetTCPUserTimeout(conn net.Conn) (int, error) { | ||||
| 	log() | ||||
| 	return -1, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										29
									
								
								vendor/google.golang.org/grpc/internal/transport/handler_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/google.golang.org/grpc/internal/transport/handler_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -63,9 +63,6 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats sta | ||||
| 	if _, ok := w.(http.Flusher); !ok { | ||||
| 		return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher") | ||||
| 	} | ||||
| 	if _, ok := w.(http.CloseNotifier); !ok { | ||||
| 		return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier") | ||||
| 	} | ||||
|  | ||||
| 	st := &serverHandlerTransport{ | ||||
| 		rw:             w, | ||||
| @@ -176,17 +173,11 @@ func (a strAddr) String() string { return string(a) } | ||||
|  | ||||
| // do runs fn in the ServeHTTP goroutine. | ||||
| func (ht *serverHandlerTransport) do(fn func()) error { | ||||
| 	// Avoid a panic writing to closed channel. Imperfect but maybe good enough. | ||||
| 	select { | ||||
| 	case <-ht.closedCh: | ||||
| 		return ErrConnClosing | ||||
| 	default: | ||||
| 		select { | ||||
| 		case ht.writes <- fn: | ||||
| 			return nil | ||||
| 		case <-ht.closedCh: | ||||
| 			return ErrConnClosing | ||||
| 		} | ||||
| 	case ht.writes <- fn: | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -237,7 +228,6 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro | ||||
| 		if ht.stats != nil { | ||||
| 			ht.stats.HandleRPC(s.Context(), &stats.OutTrailer{}) | ||||
| 		} | ||||
| 		close(ht.writes) | ||||
| 	} | ||||
| 	ht.Close() | ||||
| 	return err | ||||
| @@ -315,19 +305,13 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace | ||||
| 		ctx, cancel = context.WithCancel(ctx) | ||||
| 	} | ||||
|  | ||||
| 	// requestOver is closed when either the request's context is done | ||||
| 	// or the status has been written via WriteStatus. | ||||
| 	// requestOver is closed when the status has been written via WriteStatus. | ||||
| 	requestOver := make(chan struct{}) | ||||
|  | ||||
| 	// clientGone receives a single value if peer is gone, either | ||||
| 	// because the underlying connection is dead or because the | ||||
| 	// peer sends an http2 RST_STREAM. | ||||
| 	clientGone := ht.rw.(http.CloseNotifier).CloseNotify() | ||||
| 	go func() { | ||||
| 		select { | ||||
| 		case <-requestOver: | ||||
| 		case <-ht.closedCh: | ||||
| 		case <-clientGone: | ||||
| 		case <-ht.req.Context().Done(): | ||||
| 		} | ||||
| 		cancel() | ||||
| 		ht.Close() | ||||
| @@ -407,10 +391,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace | ||||
| func (ht *serverHandlerTransport) runStream() { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case fn, ok := <-ht.writes: | ||||
| 			if !ok { | ||||
| 				return | ||||
| 			} | ||||
| 		case fn := <-ht.writes: | ||||
| 			fn() | ||||
| 		case <-ht.closedCh: | ||||
| 			return | ||||
|   | ||||
							
								
								
									
										47
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1140,15 +1140,27 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
| 	endStream := frame.StreamEnded() | ||||
| 	atomic.StoreUint32(&s.bytesReceived, 1) | ||||
| 	var state decodeState | ||||
| 	if err := state.decodeHeader(frame); err != nil { | ||||
| 		t.closeStream(s, err, true, http2.ErrCodeProtocol, status.New(codes.Internal, err.Error()), nil, false) | ||||
| 		// Something wrong. Stops reading even when there is remaining. | ||||
| 	initialHeader := atomic.SwapUint32(&s.headerDone, 1) == 0 | ||||
|  | ||||
| 	if !initialHeader && !endStream { | ||||
| 		// As specified by RFC 7540, a HEADERS frame (and associated CONTINUATION frames) can only appear | ||||
| 		// at the start or end of a stream. Therefore, second HEADERS frame must have EOS bit set. | ||||
| 		st := status.New(codes.Internal, "a HEADERS frame cannot appear in the middle of a stream") | ||||
| 		t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, false) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	state := &decodeState{} | ||||
| 	// Initialize isGRPC value to be !initialHeader, since if a gRPC ResponseHeader has been received | ||||
| 	// which indicates peer speaking gRPC, we are in gRPC mode. | ||||
| 	state.data.isGRPC = !initialHeader | ||||
| 	if err := state.decodeHeader(frame); err != nil { | ||||
| 		t.closeStream(s, err, true, http2.ErrCodeProtocol, status.Convert(err), nil, endStream) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	endStream := frame.StreamEnded() | ||||
| 	var isHeader bool | ||||
| 	defer func() { | ||||
| 		if t.statsHandler != nil { | ||||
| @@ -1167,29 +1179,30 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	// If headers haven't been received yet. | ||||
| 	if atomic.SwapUint32(&s.headerDone, 1) == 0 { | ||||
| 	if initialHeader { | ||||
| 		if !endStream { | ||||
| 			// Headers frame is not actually a trailers-only frame. | ||||
| 			// Headers frame is ResponseHeader. | ||||
| 			isHeader = true | ||||
| 			// These values can be set without any synchronization because | ||||
| 			// stream goroutine will read it only after seeing a closed | ||||
| 			// headerChan which we'll close after setting this. | ||||
| 			s.recvCompress = state.encoding | ||||
| 			if len(state.mdata) > 0 { | ||||
| 				s.header = state.mdata | ||||
| 			s.recvCompress = state.data.encoding | ||||
| 			if len(state.data.mdata) > 0 { | ||||
| 				s.header = state.data.mdata | ||||
| 			} | ||||
| 		} else { | ||||
| 			s.noHeaders = true | ||||
| 			close(s.headerChan) | ||||
| 			return | ||||
| 		} | ||||
| 		// Headers frame is Trailers-only. | ||||
| 		s.noHeaders = true | ||||
| 		close(s.headerChan) | ||||
| 	} | ||||
| 	if !endStream { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// if client received END_STREAM from server while stream was still active, send RST_STREAM | ||||
| 	rst := s.getState() == streamActive | ||||
| 	t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, state.status(), state.mdata, true) | ||||
| 	t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, state.status(), state.data.mdata, true) | ||||
| } | ||||
|  | ||||
| // reader runs as a separate goroutine in charge of reading data from network | ||||
| @@ -1356,6 +1369,8 @@ func (t *http2Client) ChannelzMetric() *channelz.SocketInternalMetric { | ||||
| 	return &s | ||||
| } | ||||
|  | ||||
| func (t *http2Client) RemoteAddr() net.Addr { return t.remoteAddr } | ||||
|  | ||||
| func (t *http2Client) IncrMsgSent() { | ||||
| 	atomic.AddInt64(&t.czData.msgSent, 1) | ||||
| 	atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) | ||||
|   | ||||
							
								
								
									
										139
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										139
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -286,7 +286,9 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err | ||||
| // operateHeader takes action on the decoded headers. | ||||
| func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) { | ||||
| 	streamID := frame.Header().StreamID | ||||
| 	state := decodeState{serverSide: true} | ||||
| 	state := &decodeState{ | ||||
| 		serverSide: true, | ||||
| 	} | ||||
| 	if err := state.decodeHeader(frame); err != nil { | ||||
| 		if se, ok := status.FromError(err); ok { | ||||
| 			t.controlBuf.put(&cleanupStream{ | ||||
| @@ -305,16 +307,16 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( | ||||
| 		st:             t, | ||||
| 		buf:            buf, | ||||
| 		fc:             &inFlow{limit: uint32(t.initialWindowSize)}, | ||||
| 		recvCompress:   state.encoding, | ||||
| 		method:         state.method, | ||||
| 		contentSubtype: state.contentSubtype, | ||||
| 		recvCompress:   state.data.encoding, | ||||
| 		method:         state.data.method, | ||||
| 		contentSubtype: state.data.contentSubtype, | ||||
| 	} | ||||
| 	if frame.StreamEnded() { | ||||
| 		// s is just created by the caller. No lock needed. | ||||
| 		s.state = streamReadDone | ||||
| 	} | ||||
| 	if state.timeoutSet { | ||||
| 		s.ctx, s.cancel = context.WithTimeout(t.ctx, state.timeout) | ||||
| 	if state.data.timeoutSet { | ||||
| 		s.ctx, s.cancel = context.WithTimeout(t.ctx, state.data.timeout) | ||||
| 	} else { | ||||
| 		s.ctx, s.cancel = context.WithCancel(t.ctx) | ||||
| 	} | ||||
| @@ -327,19 +329,19 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( | ||||
| 	} | ||||
| 	s.ctx = peer.NewContext(s.ctx, pr) | ||||
| 	// Attach the received metadata to the context. | ||||
| 	if len(state.mdata) > 0 { | ||||
| 		s.ctx = metadata.NewIncomingContext(s.ctx, state.mdata) | ||||
| 	if len(state.data.mdata) > 0 { | ||||
| 		s.ctx = metadata.NewIncomingContext(s.ctx, state.data.mdata) | ||||
| 	} | ||||
| 	if state.statsTags != nil { | ||||
| 		s.ctx = stats.SetIncomingTags(s.ctx, state.statsTags) | ||||
| 	if state.data.statsTags != nil { | ||||
| 		s.ctx = stats.SetIncomingTags(s.ctx, state.data.statsTags) | ||||
| 	} | ||||
| 	if state.statsTrace != nil { | ||||
| 		s.ctx = stats.SetIncomingTrace(s.ctx, state.statsTrace) | ||||
| 	if state.data.statsTrace != nil { | ||||
| 		s.ctx = stats.SetIncomingTrace(s.ctx, state.data.statsTrace) | ||||
| 	} | ||||
| 	if t.inTapHandle != nil { | ||||
| 		var err error | ||||
| 		info := &tap.Info{ | ||||
| 			FullMethodName: state.method, | ||||
| 			FullMethodName: state.data.method, | ||||
| 		} | ||||
| 		s.ctx, err = t.inTapHandle(s.ctx, info) | ||||
| 		if err != nil { | ||||
| @@ -435,7 +437,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. | ||||
| 				s := t.activeStreams[se.StreamID] | ||||
| 				t.mu.Unlock() | ||||
| 				if s != nil { | ||||
| 					t.closeStream(s, true, se.Code, nil, false) | ||||
| 					t.closeStream(s, true, se.Code, false) | ||||
| 				} else { | ||||
| 					t.controlBuf.put(&cleanupStream{ | ||||
| 						streamID: se.StreamID, | ||||
| @@ -577,7 +579,7 @@ func (t *http2Server) handleData(f *http2.DataFrame) { | ||||
| 	} | ||||
| 	if size > 0 { | ||||
| 		if err := s.fc.onData(size); err != nil { | ||||
| 			t.closeStream(s, true, http2.ErrCodeFlowControl, nil, false) | ||||
| 			t.closeStream(s, true, http2.ErrCodeFlowControl, false) | ||||
| 			return | ||||
| 		} | ||||
| 		if f.Header().Flags.Has(http2.FlagDataPadded) { | ||||
| @@ -602,11 +604,18 @@ func (t *http2Server) handleData(f *http2.DataFrame) { | ||||
| } | ||||
|  | ||||
| func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) { | ||||
| 	s, ok := t.getStream(f) | ||||
| 	if !ok { | ||||
| 	// If the stream is not deleted from the transport's active streams map, then do a regular close stream. | ||||
| 	if s, ok := t.getStream(f); ok { | ||||
| 		t.closeStream(s, false, 0, false) | ||||
| 		return | ||||
| 	} | ||||
| 	t.closeStream(s, false, 0, nil, false) | ||||
| 	// If the stream is already deleted from the active streams map, then put a cleanupStream item into controlbuf to delete the stream from loopy writer's established streams map. | ||||
| 	t.controlBuf.put(&cleanupStream{ | ||||
| 		streamID: f.Header().StreamID, | ||||
| 		rst:      false, | ||||
| 		rstCode:  0, | ||||
| 		onWrite:  func() {}, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (t *http2Server) handleSettings(f *http2.SettingsFrame) { | ||||
| @@ -770,7 +779,7 @@ func (t *http2Server) writeHeaderLocked(s *Stream) error { | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		t.closeStream(s, true, http2.ErrCodeInternal, nil, false) | ||||
| 		t.closeStream(s, true, http2.ErrCodeInternal, false) | ||||
| 		return ErrHeaderListSizeLimitViolation | ||||
| 	} | ||||
| 	if t.stats != nil { | ||||
| @@ -834,10 +843,12 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		t.closeStream(s, true, http2.ErrCodeInternal, nil, false) | ||||
| 		t.closeStream(s, true, http2.ErrCodeInternal, false) | ||||
| 		return ErrHeaderListSizeLimitViolation | ||||
| 	} | ||||
| 	t.closeStream(s, false, 0, trailingHeader, true) | ||||
| 	// Send a RST_STREAM after the trailers if the client has not already half-closed. | ||||
| 	rst := s.getState() == streamActive | ||||
| 	t.finishStream(s, rst, http2.ErrCodeNo, trailingHeader, true) | ||||
| 	if t.stats != nil { | ||||
| 		t.stats.HandleRPC(s.Context(), &stats.OutTrailer{}) | ||||
| 	} | ||||
| @@ -849,6 +860,9 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { | ||||
| func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) error { | ||||
| 	if !s.isHeaderSent() { // Headers haven't been written yet. | ||||
| 		if err := t.WriteHeader(s, nil); err != nil { | ||||
| 			if _, ok := err.(ConnectionError); ok { | ||||
| 				return err | ||||
| 			} | ||||
| 			// TODO(mmukhi, dfawley): Make sure this is the right code to return. | ||||
| 			return status.Errorf(codes.Internal, "transport: %v", err) | ||||
| 		} | ||||
| @@ -1005,16 +1019,24 @@ func (t *http2Server) Close() error { | ||||
| } | ||||
|  | ||||
| // deleteStream deletes the stream s from transport's active streams. | ||||
| func (t *http2Server) deleteStream(s *Stream, eosReceived bool) { | ||||
| 	t.mu.Lock() | ||||
| 	if _, ok := t.activeStreams[s.id]; !ok { | ||||
| 		t.mu.Unlock() | ||||
| 		return | ||||
| func (t *http2Server) deleteStream(s *Stream, eosReceived bool) (oldState streamState) { | ||||
| 	oldState = s.swapState(streamDone) | ||||
| 	if oldState == streamDone { | ||||
| 		// If the stream was already done, return. | ||||
| 		return oldState | ||||
| 	} | ||||
|  | ||||
| 	delete(t.activeStreams, s.id) | ||||
| 	if len(t.activeStreams) == 0 { | ||||
| 		t.idle = time.Now() | ||||
| 	// In case stream sending and receiving are invoked in separate | ||||
| 	// goroutines (e.g., bi-directional streaming), cancel needs to be | ||||
| 	// called to interrupt the potential blocking on other goroutines. | ||||
| 	s.cancel() | ||||
|  | ||||
| 	t.mu.Lock() | ||||
| 	if _, ok := t.activeStreams[s.id]; ok { | ||||
| 		delete(t.activeStreams, s.id) | ||||
| 		if len(t.activeStreams) == 0 { | ||||
| 			t.idle = time.Now() | ||||
| 		} | ||||
| 	} | ||||
| 	t.mu.Unlock() | ||||
|  | ||||
| @@ -1025,55 +1047,38 @@ func (t *http2Server) deleteStream(s *Stream, eosReceived bool) { | ||||
| 			atomic.AddInt64(&t.czData.streamsFailed, 1) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return oldState | ||||
| } | ||||
|  | ||||
| // closeStream clears the footprint of a stream when the stream is not needed | ||||
| // any more. | ||||
| func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { | ||||
| 	// Mark the stream as done | ||||
| 	oldState := s.swapState(streamDone) | ||||
| // finishStream closes the stream and puts the trailing headerFrame into controlbuf. | ||||
| func (t *http2Server) finishStream(s *Stream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { | ||||
| 	oldState := t.deleteStream(s, eosReceived) | ||||
| 	// If the stream is already closed, then don't put trailing header to controlbuf. | ||||
| 	if oldState == streamDone { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// In case stream sending and receiving are invoked in separate | ||||
| 	// goroutines (e.g., bi-directional streaming), cancel needs to be | ||||
| 	// called to interrupt the potential blocking on other goroutines. | ||||
| 	s.cancel() | ||||
|  | ||||
| 	// Deletes the stream from active streams | ||||
| 	t.deleteStream(s, eosReceived) | ||||
|  | ||||
| 	cleanup := &cleanupStream{ | ||||
| 	hdr.cleanup = &cleanupStream{ | ||||
| 		streamID: s.id, | ||||
| 		rst:      rst, | ||||
| 		rstCode:  rstCode, | ||||
| 		onWrite:  func() {}, | ||||
| 	} | ||||
|  | ||||
| 	// No trailer. Puts cleanupFrame into transport's control buffer. | ||||
| 	if hdr == nil { | ||||
| 		t.controlBuf.put(cleanup) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// We do the check here, because of the following scenario: | ||||
| 	// 1. closeStream is called first with a trailer. A trailer item with a piggybacked cleanup item | ||||
| 	// is put to control buffer. | ||||
| 	// 2. Loopy writer is waiting on a stream quota. It will never get it because client errored at | ||||
| 	// some point. So loopy can't act on trailer | ||||
| 	// 3. Client sends a RST_STREAM due to the error. Then closeStream is called without a trailer as | ||||
| 	// the result of the received RST_STREAM. | ||||
| 	// If we do this check at the beginning of the closeStream, then we won't put a cleanup item in | ||||
| 	// response to received RST_STREAM into the control buffer and outStream in loopy writer will | ||||
| 	// never get cleaned up. | ||||
|  | ||||
| 	// If the stream is already done, don't send the trailer. | ||||
| 	if oldState == streamDone { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	hdr.cleanup = cleanup | ||||
| 	t.controlBuf.put(hdr) | ||||
| } | ||||
|  | ||||
| // closeStream clears the footprint of a stream when the stream is not needed any more. | ||||
| func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, eosReceived bool) { | ||||
| 	t.deleteStream(s, eosReceived) | ||||
| 	t.controlBuf.put(&cleanupStream{ | ||||
| 		streamID: s.id, | ||||
| 		rst:      rst, | ||||
| 		rstCode:  rstCode, | ||||
| 		onWrite:  func() {}, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (t *http2Server) RemoteAddr() net.Addr { | ||||
| 	return t.remoteAddr | ||||
| } | ||||
|   | ||||
							
								
								
									
										167
									
								
								vendor/google.golang.org/grpc/internal/transport/http_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										167
									
								
								vendor/google.golang.org/grpc/internal/transport/http_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -78,7 +78,8 @@ var ( | ||||
| 		codes.ResourceExhausted: http2.ErrCodeEnhanceYourCalm, | ||||
| 		codes.PermissionDenied:  http2.ErrCodeInadequateSecurity, | ||||
| 	} | ||||
| 	httpStatusConvTab = map[int]codes.Code{ | ||||
| 	// HTTPStatusConvTab is the HTTP status code to gRPC error code conversion table. | ||||
| 	HTTPStatusConvTab = map[int]codes.Code{ | ||||
| 		// 400 Bad Request - INTERNAL. | ||||
| 		http.StatusBadRequest: codes.Internal, | ||||
| 		// 401 Unauthorized  - UNAUTHENTICATED. | ||||
| @@ -98,9 +99,7 @@ var ( | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // Records the states during HPACK decoding. Must be reset once the | ||||
| // decoding of the entire headers are finished. | ||||
| type decodeState struct { | ||||
| type parsedHeaderData struct { | ||||
| 	encoding string | ||||
| 	// statusGen caches the stream status received from the trailer the server | ||||
| 	// sent.  Client side only.  Do not access directly.  After all trailers are | ||||
| @@ -120,8 +119,30 @@ type decodeState struct { | ||||
| 	statsTags      []byte | ||||
| 	statsTrace     []byte | ||||
| 	contentSubtype string | ||||
|  | ||||
| 	// isGRPC field indicates whether the peer is speaking gRPC (otherwise HTTP). | ||||
| 	// | ||||
| 	// We are in gRPC mode (peer speaking gRPC) if: | ||||
| 	// 	* We are client side and have already received a HEADER frame that indicates gRPC peer. | ||||
| 	//  * The header contains valid  a content-type, i.e. a string starts with "application/grpc" | ||||
| 	// And we should handle error specific to gRPC. | ||||
| 	// | ||||
| 	// Otherwise (i.e. a content-type string starts without "application/grpc", or does not exist), we | ||||
| 	// are in HTTP fallback mode, and should handle error specific to HTTP. | ||||
| 	isGRPC         bool | ||||
| 	grpcErr        error | ||||
| 	httpErr        error | ||||
| 	contentTypeErr string | ||||
| } | ||||
|  | ||||
| // decodeState configures decoding criteria and records the decoded data. | ||||
| type decodeState struct { | ||||
| 	// whether decoding on server side or not | ||||
| 	serverSide bool | ||||
|  | ||||
| 	// Records the states during HPACK decoding. It will be filled with info parsed from HTTP HEADERS | ||||
| 	// frame once decodeHeader function has been invoked and returned. | ||||
| 	data parsedHeaderData | ||||
| } | ||||
|  | ||||
| // isReservedHeader checks whether hdr belongs to HTTP2 headers | ||||
| @@ -202,11 +223,11 @@ func contentType(contentSubtype string) string { | ||||
| } | ||||
|  | ||||
| func (d *decodeState) status() *status.Status { | ||||
| 	if d.statusGen == nil { | ||||
| 	if d.data.statusGen == nil { | ||||
| 		// No status-details were provided; generate status using code/msg. | ||||
| 		d.statusGen = status.New(codes.Code(int32(*(d.rawStatusCode))), d.rawStatusMsg) | ||||
| 		d.data.statusGen = status.New(codes.Code(int32(*(d.data.rawStatusCode))), d.data.rawStatusMsg) | ||||
| 	} | ||||
| 	return d.statusGen | ||||
| 	return d.data.statusGen | ||||
| } | ||||
|  | ||||
| const binHdrSuffix = "-bin" | ||||
| @@ -244,113 +265,146 @@ func (d *decodeState) decodeHeader(frame *http2.MetaHeadersFrame) error { | ||||
| 	if frame.Truncated { | ||||
| 		return status.Error(codes.Internal, "peer header list size exceeded limit") | ||||
| 	} | ||||
|  | ||||
| 	for _, hf := range frame.Fields { | ||||
| 		if err := d.processHeaderField(hf); err != nil { | ||||
| 			return err | ||||
| 		d.processHeaderField(hf) | ||||
| 	} | ||||
|  | ||||
| 	if d.data.isGRPC { | ||||
| 		if d.data.grpcErr != nil { | ||||
| 			return d.data.grpcErr | ||||
| 		} | ||||
| 		if d.serverSide { | ||||
| 			return nil | ||||
| 		} | ||||
| 		if d.data.rawStatusCode == nil && d.data.statusGen == nil { | ||||
| 			// gRPC status doesn't exist. | ||||
| 			// Set rawStatusCode to be unknown and return nil error. | ||||
| 			// So that, if the stream has ended this Unknown status | ||||
| 			// will be propagated to the user. | ||||
| 			// Otherwise, it will be ignored. In which case, status from | ||||
| 			// a later trailer, that has StreamEnded flag set, is propagated. | ||||
| 			code := int(codes.Unknown) | ||||
| 			d.data.rawStatusCode = &code | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if d.serverSide { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// If grpc status exists, no need to check further. | ||||
| 	if d.rawStatusCode != nil || d.statusGen != nil { | ||||
| 		return nil | ||||
| 	// HTTP fallback mode | ||||
| 	if d.data.httpErr != nil { | ||||
| 		return d.data.httpErr | ||||
| 	} | ||||
|  | ||||
| 	// If grpc status doesn't exist and http status doesn't exist, | ||||
| 	// then it's a malformed header. | ||||
| 	if d.httpStatus == nil { | ||||
| 		return status.Error(codes.Internal, "malformed header: doesn't contain status(gRPC or HTTP)") | ||||
| 	} | ||||
| 	var ( | ||||
| 		code = codes.Internal // when header does not include HTTP status, return INTERNAL | ||||
| 		ok   bool | ||||
| 	) | ||||
|  | ||||
| 	if *(d.httpStatus) != http.StatusOK { | ||||
| 		code, ok := httpStatusConvTab[*(d.httpStatus)] | ||||
| 	if d.data.httpStatus != nil { | ||||
| 		code, ok = HTTPStatusConvTab[*(d.data.httpStatus)] | ||||
| 		if !ok { | ||||
| 			code = codes.Unknown | ||||
| 		} | ||||
| 		return status.Error(code, http.StatusText(*(d.httpStatus))) | ||||
| 	} | ||||
|  | ||||
| 	// gRPC status doesn't exist and http status is OK. | ||||
| 	// Set rawStatusCode to be unknown and return nil error. | ||||
| 	// So that, if the stream has ended this Unknown status | ||||
| 	// will be propagated to the user. | ||||
| 	// Otherwise, it will be ignored. In which case, status from | ||||
| 	// a later trailer, that has StreamEnded flag set, is propagated. | ||||
| 	code := int(codes.Unknown) | ||||
| 	d.rawStatusCode = &code | ||||
| 	return nil | ||||
| 	return status.Error(code, d.constructHTTPErrMsg()) | ||||
| } | ||||
|  | ||||
| // constructErrMsg constructs error message to be returned in HTTP fallback mode. | ||||
| // Format: HTTP status code and its corresponding message + content-type error message. | ||||
| func (d *decodeState) constructHTTPErrMsg() string { | ||||
| 	var errMsgs []string | ||||
|  | ||||
| 	if d.data.httpStatus == nil { | ||||
| 		errMsgs = append(errMsgs, "malformed header: missing HTTP status") | ||||
| 	} else { | ||||
| 		errMsgs = append(errMsgs, fmt.Sprintf("%s: HTTP status code %d", http.StatusText(*(d.data.httpStatus)), *d.data.httpStatus)) | ||||
| 	} | ||||
|  | ||||
| 	if d.data.contentTypeErr == "" { | ||||
| 		errMsgs = append(errMsgs, "transport: missing content-type field") | ||||
| 	} else { | ||||
| 		errMsgs = append(errMsgs, d.data.contentTypeErr) | ||||
| 	} | ||||
|  | ||||
| 	return strings.Join(errMsgs, "; ") | ||||
| } | ||||
|  | ||||
| func (d *decodeState) addMetadata(k, v string) { | ||||
| 	if d.mdata == nil { | ||||
| 		d.mdata = make(map[string][]string) | ||||
| 	if d.data.mdata == nil { | ||||
| 		d.data.mdata = make(map[string][]string) | ||||
| 	} | ||||
| 	d.mdata[k] = append(d.mdata[k], v) | ||||
| 	d.data.mdata[k] = append(d.data.mdata[k], v) | ||||
| } | ||||
|  | ||||
| func (d *decodeState) processHeaderField(f hpack.HeaderField) error { | ||||
| func (d *decodeState) processHeaderField(f hpack.HeaderField) { | ||||
| 	switch f.Name { | ||||
| 	case "content-type": | ||||
| 		contentSubtype, validContentType := contentSubtype(f.Value) | ||||
| 		if !validContentType { | ||||
| 			return status.Errorf(codes.Internal, "transport: received the unexpected content-type %q", f.Value) | ||||
| 			d.data.contentTypeErr = fmt.Sprintf("transport: received the unexpected content-type %q", f.Value) | ||||
| 			return | ||||
| 		} | ||||
| 		d.contentSubtype = contentSubtype | ||||
| 		d.data.contentSubtype = contentSubtype | ||||
| 		// TODO: do we want to propagate the whole content-type in the metadata, | ||||
| 		// or come up with a way to just propagate the content-subtype if it was set? | ||||
| 		// ie {"content-type": "application/grpc+proto"} or {"content-subtype": "proto"} | ||||
| 		// in the metadata? | ||||
| 		d.addMetadata(f.Name, f.Value) | ||||
| 		d.data.isGRPC = true | ||||
| 	case "grpc-encoding": | ||||
| 		d.encoding = f.Value | ||||
| 		d.data.encoding = f.Value | ||||
| 	case "grpc-status": | ||||
| 		code, err := strconv.Atoi(f.Value) | ||||
| 		if err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed grpc-status: %v", err) | ||||
| 			d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		d.rawStatusCode = &code | ||||
| 		d.data.rawStatusCode = &code | ||||
| 	case "grpc-message": | ||||
| 		d.rawStatusMsg = decodeGrpcMessage(f.Value) | ||||
| 		d.data.rawStatusMsg = decodeGrpcMessage(f.Value) | ||||
| 	case "grpc-status-details-bin": | ||||
| 		v, err := decodeBinHeader(f.Value) | ||||
| 		if err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) | ||||
| 			d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		s := &spb.Status{} | ||||
| 		if err := proto.Unmarshal(v, s); err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) | ||||
| 			d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		d.statusGen = status.FromProto(s) | ||||
| 		d.data.statusGen = status.FromProto(s) | ||||
| 	case "grpc-timeout": | ||||
| 		d.timeoutSet = true | ||||
| 		d.data.timeoutSet = true | ||||
| 		var err error | ||||
| 		if d.timeout, err = decodeTimeout(f.Value); err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed time-out: %v", err) | ||||
| 		if d.data.timeout, err = decodeTimeout(f.Value); err != nil { | ||||
| 			d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed time-out: %v", err) | ||||
| 		} | ||||
| 	case ":path": | ||||
| 		d.method = f.Value | ||||
| 		d.data.method = f.Value | ||||
| 	case ":status": | ||||
| 		code, err := strconv.Atoi(f.Value) | ||||
| 		if err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed http-status: %v", err) | ||||
| 			d.data.httpErr = status.Errorf(codes.Internal, "transport: malformed http-status: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		d.httpStatus = &code | ||||
| 		d.data.httpStatus = &code | ||||
| 	case "grpc-tags-bin": | ||||
| 		v, err := decodeBinHeader(f.Value) | ||||
| 		if err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err) | ||||
| 			d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		d.statsTags = v | ||||
| 		d.data.statsTags = v | ||||
| 		d.addMetadata(f.Name, string(v)) | ||||
| 	case "grpc-trace-bin": | ||||
| 		v, err := decodeBinHeader(f.Value) | ||||
| 		if err != nil { | ||||
| 			return status.Errorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err) | ||||
| 			d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		d.statsTrace = v | ||||
| 		d.data.statsTrace = v | ||||
| 		d.addMetadata(f.Name, string(v)) | ||||
| 	default: | ||||
| 		if isReservedHeader(f.Name) && !isWhitelistedHeader(f.Name) { | ||||
| @@ -359,11 +413,10 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) error { | ||||
| 		v, err := decodeMetadataHeader(f.Name, f.Value) | ||||
| 		if err != nil { | ||||
| 			errorf("Failed to decode metadata header (%q, %q): %v", f.Name, f.Value, err) | ||||
| 			return nil | ||||
| 			return | ||||
| 		} | ||||
| 		d.addMetadata(f.Name, v) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type timeoutUnit uint8 | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/google.golang.org/grpc/internal/transport/transport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/google.golang.org/grpc/internal/transport/transport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -327,8 +327,7 @@ func (s *Stream) TrailersOnly() (bool, error) { | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	// if !headerDone, some other connection error occurred. | ||||
| 	return s.noHeaders && atomic.LoadUint32(&s.headerDone) == 1, nil | ||||
| 	return s.noHeaders, nil | ||||
| } | ||||
|  | ||||
| // Trailer returns the cached trailer metedata. Note that if it is not called | ||||
| @@ -611,6 +610,9 @@ type ClientTransport interface { | ||||
| 	// GetGoAwayReason returns the reason why GoAway frame was received. | ||||
| 	GetGoAwayReason() GoAwayReason | ||||
|  | ||||
| 	// RemoteAddr returns the remote network address. | ||||
| 	RemoteAddr() net.Addr | ||||
|  | ||||
| 	// IncrMsgSent increments the number of message sent through this transport. | ||||
| 	IncrMsgSent() | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tonis Tiigi
					Tonis Tiigi