propose: contrib/net/http: add conditional propagation logic to roundTripper configuration
I want to determine whether to propagate or not for each api I call. For example, when calling a external api, no propagation is performed. I assume the following code.
// https://github.com/DataDog/dd-trace-go/blob/e4985df5f9ef6a5b1f5cc9f72b03ddddcb4af0bc/contrib/net/http/option.go#L138
type roundTripperConfig struct {
// ...
+ propagationFunc func(*http.Request) bool
// ...
}
func (rt *roundTripper) RoundTrip(req *http.Request) (res *http.Response, err error) {
// ...
// https://github.com/DataDog/dd-trace-go/blob/e4985df5f9ef6a5b1f5cc9f72b03ddddcb4af0bc/contrib/net/http/roundtripper.go#L73
- if rt.cfg.propagation {
+ if rt.cfg.propagation && rt.cfg.propagationFunc(r2) {
Hello @eyasy1217, thanks for reaching out. We'll review this during our next gardening session.
@eyasy1217 What would be the use case? We found it interesting and we are willing to implement it, but we would like to understand the use case. For instance, is it to avoid sending propagation headers to a third party API that isn't able to handle correctly unknown headers?
It's not such a big use case. Same reason as https://github.com/DataDog/dd-trace-go/issues/1166 .
we have encountered third party api's that limit the # of headers we can send in our requests, being able to disable the propagation headers for that specific request would be useful addition
@davekerr-orum and/or @eyasy1217 , are you able to share the third party API(s) enforcing this limit? An example would be useful for us to better understand the scope of this problem.
For anyone interested, you can achieve the desired behavior by chaining your our custom transport with the Datadog one.
Example:
type removeDDHeadersTransport struct {
base http.RoundTripper
}
func (i *removeDDHeadersTransport) RoundTrip(req *http.Request) (*http.Response, error) {
for name, _ := range req.Header {
if strings.HasPrefix(name, "X-Datadog") {
fmt.Printf("removing Datadog header: %s\n", name)
req.Header.Del(name)
}
}
return i.base.RoundTrip(req)
}
func main() {
// ... initialize the tracer etc.
rt := httptrace.WrapRoundTripper(&removeDDHeadersTransport{base: http.DefaultTransport})
client := &http.Client{Transport: rt}
// do stuff with client
}