mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 22:52:25 -05:00 
			
		
		
		
	[feature] Support OTLP HTTP, drop Jaeger (#2184)
* [feature] Add http trace exporter, drop Jaeger Jaeger supports ingesting traces using the OpenTelemetry gRPC or HTTP methods. The Jaeger project has deprecated the old jaeger transport. * Add support for submitting traces over HTTP * Drop support for the old Jaeger protocol * Upgrade the trace libraries to v1.17 Fixes: #2176 Fixes: #2179
This commit is contained in:
		
					parent
					
						
							
								916c6d07ba
							
						
					
				
			
			
				commit
				
					
						14ef098099
					
				
			
		
					 199 changed files with 12972 additions and 18581 deletions
				
			
		
							
								
								
									
										162
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -6,10 +6,13 @@ import ( | |||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/textproto" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule" | ||||
| 	"google.golang.org/grpc/codes" | ||||
| 	"google.golang.org/grpc/grpclog" | ||||
| 	"google.golang.org/grpc/health/grpc_health_v1" | ||||
| 	"google.golang.org/grpc/metadata" | ||||
| 	"google.golang.org/grpc/status" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
|  | @ -23,15 +26,15 @@ const ( | |||
| 	// path string before doing any routing. | ||||
| 	UnescapingModeLegacy UnescapingMode = iota | ||||
| 
 | ||||
| 	// EscapingTypeExceptReserved unescapes all path parameters except RFC 6570 | ||||
| 	// UnescapingModeAllExceptReserved unescapes all path parameters except RFC 6570 | ||||
| 	// reserved characters. | ||||
| 	UnescapingModeAllExceptReserved | ||||
| 
 | ||||
| 	// EscapingTypeExceptSlash unescapes URL path parameters except path | ||||
| 	// seperators, which will be left as "%2F". | ||||
| 	// UnescapingModeAllExceptSlash unescapes URL path parameters except path | ||||
| 	// separators, which will be left as "%2F". | ||||
| 	UnescapingModeAllExceptSlash | ||||
| 
 | ||||
| 	// URL path parameters will be fully decoded. | ||||
| 	// UnescapingModeAllCharacters unescapes all URL path parameters. | ||||
| 	UnescapingModeAllCharacters | ||||
| 
 | ||||
| 	// UnescapingModeDefault is the default escaping type. | ||||
|  | @ -40,6 +43,8 @@ const ( | |||
| 	UnescapingModeDefault = UnescapingModeLegacy | ||||
| ) | ||||
| 
 | ||||
| var encodedPathSplitter = regexp.MustCompile("(/|%2F)") | ||||
| 
 | ||||
| // A HandlerFunc handles a specific pair of path pattern and HTTP method. | ||||
| type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) | ||||
| 
 | ||||
|  | @ -75,7 +80,7 @@ func WithForwardResponseOption(forwardResponseOption func(context.Context, http. | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // WithEscapingType sets the escaping type. See the definitions of UnescapingMode | ||||
| // WithUnescapingMode sets the escaping type. See the definitions of UnescapingMode | ||||
| // for more information. | ||||
| func WithUnescapingMode(mode UnescapingMode) ServeMuxOption { | ||||
| 	return func(serveMux *ServeMux) { | ||||
|  | @ -96,13 +101,14 @@ func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMux | |||
| type HeaderMatcherFunc func(string) (string, bool) | ||||
| 
 | ||||
| // DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header | ||||
| // keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with | ||||
| // 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'. | ||||
| // keys (as specified by the IANA, e.g: Accept, Cookie, Host) to the gRPC metadata with the grpcgateway- prefix. If you want to know which headers are considered permanent, you can view the isPermanentHTTPHeader function. | ||||
| // HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata after removing the prefix 'Grpc-Metadata-'. | ||||
| // Other headers are not added to the gRPC metadata. | ||||
| func DefaultHeaderMatcher(key string) (string, bool) { | ||||
| 	key = textproto.CanonicalMIMEHeaderKey(key) | ||||
| 	if isPermanentHTTPHeader(key) { | ||||
| 	switch key = textproto.CanonicalMIMEHeaderKey(key); { | ||||
| 	case isPermanentHTTPHeader(key): | ||||
| 		return MetadataPrefix + key, true | ||||
| 	} else if strings.HasPrefix(key, MetadataHeaderPrefix) { | ||||
| 	case strings.HasPrefix(key, MetadataHeaderPrefix): | ||||
| 		return key[len(MetadataHeaderPrefix):], true | ||||
| 	} | ||||
| 	return "", false | ||||
|  | @ -113,11 +119,30 @@ func DefaultHeaderMatcher(key string) (string, bool) { | |||
| // This matcher will be called with each header in http.Request. If matcher returns true, that header will be | ||||
| // passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. | ||||
| func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { | ||||
| 	for _, header := range fn.matchedMalformedHeaders() { | ||||
| 		grpclog.Warningf("The configured forwarding filter would allow %q to be sent to the gRPC server, which will likely cause errors. See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more information.", header) | ||||
| 	} | ||||
| 
 | ||||
| 	return func(mux *ServeMux) { | ||||
| 		mux.incomingHeaderMatcher = fn | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // matchedMalformedHeaders returns the malformed headers that would be forwarded to gRPC server. | ||||
| func (fn HeaderMatcherFunc) matchedMalformedHeaders() []string { | ||||
| 	if fn == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	headers := make([]string, 0) | ||||
| 	for header := range malformedHTTPHeaders { | ||||
| 		out, accept := fn(header) | ||||
| 		if accept && isMalformedHTTPHeader(out) { | ||||
| 			headers = append(headers, out) | ||||
| 		} | ||||
| 	} | ||||
| 	return headers | ||||
| } | ||||
| 
 | ||||
| // WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. | ||||
| // | ||||
| // This matcher will be called with each header in response header metadata. If matcher returns true, that header will be | ||||
|  | @ -179,6 +204,56 @@ func WithDisablePathLengthFallback() ServeMuxOption { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // WithHealthEndpointAt returns a ServeMuxOption that will add an endpoint to the created ServeMux at the path specified by endpointPath. | ||||
| // When called the handler will forward the request to the upstream grpc service health check (defined in the | ||||
| // gRPC Health Checking Protocol). | ||||
| // | ||||
| // See here https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/health_check/ for more information on how | ||||
| // to setup the protocol in the grpc server. | ||||
| // | ||||
| // If you define a service as query parameter, this will also be forwarded as service in the HealthCheckRequest. | ||||
| func WithHealthEndpointAt(healthCheckClient grpc_health_v1.HealthClient, endpointPath string) ServeMuxOption { | ||||
| 	return func(s *ServeMux) { | ||||
| 		// error can be ignored since pattern is definitely valid | ||||
| 		_ = s.HandlePath( | ||||
| 			http.MethodGet, endpointPath, func(w http.ResponseWriter, r *http.Request, _ map[string]string, | ||||
| 			) { | ||||
| 				_, outboundMarshaler := MarshalerForRequest(s, r) | ||||
| 
 | ||||
| 				resp, err := healthCheckClient.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{ | ||||
| 					Service: r.URL.Query().Get("service"), | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err) | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				w.Header().Set("Content-Type", "application/json") | ||||
| 
 | ||||
| 				if resp.GetStatus() != grpc_health_v1.HealthCheckResponse_SERVING { | ||||
| 					switch resp.GetStatus() { | ||||
| 					case grpc_health_v1.HealthCheckResponse_NOT_SERVING, grpc_health_v1.HealthCheckResponse_UNKNOWN: | ||||
| 						err = status.Error(codes.Unavailable, resp.String()) | ||||
| 					case grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN: | ||||
| 						err = status.Error(codes.NotFound, resp.String()) | ||||
| 					} | ||||
| 
 | ||||
| 					s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err) | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				_ = outboundMarshaler.NewEncoder(w).Encode(resp) | ||||
| 			}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // WithHealthzEndpoint returns a ServeMuxOption that will add a /healthz endpoint to the created ServeMux. | ||||
| // | ||||
| // See WithHealthEndpointAt for the general implementation. | ||||
| func WithHealthzEndpoint(healthCheckClient grpc_health_v1.HealthClient) ServeMuxOption { | ||||
| 	return WithHealthEndpointAt(healthCheckClient, "/healthz") | ||||
| } | ||||
| 
 | ||||
| // NewServeMux returns a new ServeMux whose internal mapping is empty. | ||||
| func NewServeMux(opts ...ServeMuxOption) *ServeMux { | ||||
| 	serveMux := &ServeMux{ | ||||
|  | @ -229,7 +304,7 @@ func (s *ServeMux) HandlePath(meth string, pathPattern string, h HandlerFunc) er | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. | ||||
| // ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.URL.Path. | ||||
| func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	ctx := r.Context() | ||||
| 
 | ||||
|  | @ -245,8 +320,6 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
| 		path = r.URL.RawPath | ||||
| 	} | ||||
| 
 | ||||
| 	components := strings.Split(path[1:], "/") | ||||
| 
 | ||||
| 	if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { | ||||
| 		r.Method = strings.ToUpper(override) | ||||
| 		if err := r.ParseForm(); err != nil { | ||||
|  | @ -257,8 +330,18 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Verb out here is to memoize for the fallback case below | ||||
| 	var verb string | ||||
| 	var pathComponents []string | ||||
| 	// since in UnescapeModeLegacy, the URL will already have been fully unescaped, if we also split on "%2F" | ||||
| 	// in this escaping mode we would be double unescaping but in UnescapingModeAllCharacters, we still do as the | ||||
| 	// path is the RawPath (i.e. unescaped). That does mean that the behavior of this function will change its default | ||||
| 	// behavior when the UnescapingModeDefault gets changed from UnescapingModeLegacy to UnescapingModeAllExceptReserved | ||||
| 	if s.unescapingMode == UnescapingModeAllCharacters { | ||||
| 		pathComponents = encodedPathSplitter.Split(path[1:], -1) | ||||
| 	} else { | ||||
| 		pathComponents = strings.Split(path[1:], "/") | ||||
| 	} | ||||
| 
 | ||||
| 	lastPathComponent := pathComponents[len(pathComponents)-1] | ||||
| 
 | ||||
| 	for _, h := range s.handlers[r.Method] { | ||||
| 		// If the pattern has a verb, explicitly look for a suffix in the last | ||||
|  | @ -269,23 +352,28 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
| 		// parser because we know what verb we're looking for, however, there | ||||
| 		// are still some cases that the parser itself cannot disambiguate. See | ||||
| 		// the comment there if interested. | ||||
| 
 | ||||
| 		var verb string | ||||
| 		patVerb := h.pat.Verb() | ||||
| 		l := len(components) | ||||
| 		lastComponent := components[l-1] | ||||
| 		var idx int = -1 | ||||
| 		if patVerb != "" && strings.HasSuffix(lastComponent, ":"+patVerb) { | ||||
| 			idx = len(lastComponent) - len(patVerb) - 1 | ||||
| 
 | ||||
| 		idx := -1 | ||||
| 		if patVerb != "" && strings.HasSuffix(lastPathComponent, ":"+patVerb) { | ||||
| 			idx = len(lastPathComponent) - len(patVerb) - 1 | ||||
| 		} | ||||
| 		if idx == 0 { | ||||
| 			_, outboundMarshaler := MarshalerForRequest(s, r) | ||||
| 			s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		comps := make([]string, len(pathComponents)) | ||||
| 		copy(comps, pathComponents) | ||||
| 
 | ||||
| 		if idx > 0 { | ||||
| 			components[l-1], verb = lastComponent[:idx], lastComponent[idx+1:] | ||||
| 			comps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:] | ||||
| 		} | ||||
| 
 | ||||
| 		pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode) | ||||
| 		pathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode) | ||||
| 		if err != nil { | ||||
| 			var mse MalformedSequenceError | ||||
| 			if ok := errors.As(err, &mse); ok { | ||||
|  | @ -301,14 +389,33 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// lookup other methods to handle fallback from GET to POST and | ||||
| 	// to determine if it is NotImplemented or NotFound. | ||||
| 	// if no handler has found for the request, lookup for other methods | ||||
| 	// to handle POST -> GET fallback if the request is subject to path | ||||
| 	// length fallback. | ||||
| 	// Note we are not eagerly checking the request here as we want to return the | ||||
| 	// right HTTP status code, and we need to process the fallback candidates in | ||||
| 	// order to do that. | ||||
| 	for m, handlers := range s.handlers { | ||||
| 		if m == r.Method { | ||||
| 			continue | ||||
| 		} | ||||
| 		for _, h := range handlers { | ||||
| 			pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode) | ||||
| 			var verb string | ||||
| 			patVerb := h.pat.Verb() | ||||
| 
 | ||||
| 			idx := -1 | ||||
| 			if patVerb != "" && strings.HasSuffix(lastPathComponent, ":"+patVerb) { | ||||
| 				idx = len(lastPathComponent) - len(patVerb) - 1 | ||||
| 			} | ||||
| 
 | ||||
| 			comps := make([]string, len(pathComponents)) | ||||
| 			copy(comps, pathComponents) | ||||
| 
 | ||||
| 			if idx > 0 { | ||||
| 				comps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:] | ||||
| 			} | ||||
| 
 | ||||
| 			pathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode) | ||||
| 			if err != nil { | ||||
| 				var mse MalformedSequenceError | ||||
| 				if ok := errors.As(err, &mse); ok { | ||||
|  | @ -320,8 +427,11 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			// X-HTTP-Method-Override is optional. Always allow fallback to POST. | ||||
| 			if s.isPathLengthFallback(r) { | ||||
| 			// Also, only consider POST -> GET fallbacks, and avoid falling back to | ||||
| 			// potentially dangerous operations like DELETE. | ||||
| 			if s.isPathLengthFallback(r) && m == http.MethodGet { | ||||
| 				if err := r.ParseForm(); err != nil { | ||||
| 					_, outboundMarshaler := MarshalerForRequest(s, r) | ||||
| 					sterr := status.Error(codes.InvalidArgument, err.Error()) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue