| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 | // Copyright 2018, OpenCensus 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 ochttpimport (	"net/http"	"net/http/httptrace"	"go.opencensus.io/trace"	"go.opencensus.io/trace/propagation")// Transport is an http.RoundTripper that instruments all outgoing requests with// OpenCensus stats and tracing.//// The zero value is intended to be a useful default, but for// now it's recommended that you explicitly set Propagation, since the default// for this may change.type Transport struct {	// Base may be set to wrap another http.RoundTripper that does the actual	// requests. By default http.DefaultTransport is used.	//	// If base HTTP roundtripper implements CancelRequest,	// the returned round tripper will be cancelable.	Base http.RoundTripper	// Propagation defines how traces are propagated. If unspecified, a default	// (currently B3 format) will be used.	Propagation propagation.HTTPFormat	// StartOptions are applied to the span started by this Transport around each	// request.	//	// StartOptions.SpanKind will always be set to trace.SpanKindClient	// for spans started by this transport.	StartOptions trace.StartOptions	// GetStartOptions allows to set start options per request. If set,	// StartOptions is going to be ignored.	GetStartOptions func(*http.Request) trace.StartOptions	// NameFromRequest holds the function to use for generating the span name	// from the information found in the outgoing HTTP Request. By default the	// name equals the URL Path.	FormatSpanName func(*http.Request) string	// NewClientTrace may be set to a function allowing the current *trace.Span	// to be annotated with HTTP request event information emitted by the	// httptrace package.	NewClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace	// TODO: Implement tag propagation for HTTP.}// RoundTrip implements http.RoundTripper, delegating to Base and recording stats and traces for the request.func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {	rt := t.base()	if isHealthEndpoint(req.URL.Path) {		return rt.RoundTrip(req)	}	// TODO: remove excessive nesting of http.RoundTrippers here.	format := t.Propagation	if format == nil {		format = defaultFormat	}	spanNameFormatter := t.FormatSpanName	if spanNameFormatter == nil {		spanNameFormatter = spanNameFromURL	}	startOpts := t.StartOptions	if t.GetStartOptions != nil {		startOpts = t.GetStartOptions(req)	}	rt = &traceTransport{		base:   rt,		format: format,		startOptions: trace.StartOptions{			Sampler:  startOpts.Sampler,			SpanKind: trace.SpanKindClient,		},		formatSpanName: spanNameFormatter,		newClientTrace: t.NewClientTrace,	}	rt = statsTransport{base: rt}	return rt.RoundTrip(req)}func (t *Transport) base() http.RoundTripper {	if t.Base != nil {		return t.Base	}	return http.DefaultTransport}// CancelRequest cancels an in-flight request by closing its connection.func (t *Transport) CancelRequest(req *http.Request) {	type canceler interface {		CancelRequest(*http.Request)	}	if cr, ok := t.base().(canceler); ok {		cr.CancelRequest(req)	}}
 |