Spring-cloud-sleuth: TraceRequestHttpHeadersFilter overrides all request headers in Spring Cloud Gateway

Created on 28 Jan 2019  路  11Comments  路  Source: spring-cloud/spring-cloud-sleuth

Oops, I'm not sure it is a bug or question.

I'm trying to integrate Spring Cloud Gateway and Spring Cloud Sleuth. In Spring Boot 2.1.2 and Spring Cloud Greenwich.RELEASE.

I found any of my request Header 'X-Forward-*' is missing.

After reading the source code, I found a HeaderFilters in the NettyRoutingFIlter and the TraceRequestHttpHeadersFilter was injected.

But TraceRequestHttpHeadersFilter is so strange. Why is its implementation covered instead of append?

class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter {
    private static final Log log = LogFactory.getLog(TraceRequestHttpHeadersFilter.class);

    static HttpHeadersFilter create(HttpTracing httpTracing) {
        return new TraceRequestHttpHeadersFilter(httpTracing);
    }

    private TraceRequestHttpHeadersFilter(HttpTracing httpTracing) {
        super(httpTracing);
    }

    public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) {
        if (log.isDebugEnabled()) {
            log.debug("Will instrument the HTTP request headers");
        }

        Builder builder = exchange.getRequest().mutate();
        Span span = this.handler.handleSend(this.injector, builder);
        if (log.isDebugEnabled()) {
            log.debug("Client span  " + span + " created for the request. New headers are " + builder.build().getHeaders().toSingleValueMap());
        }

        exchange.getAttributes().put(SPAN_ATTRIBUTE, span);
        return new HttpHeaders(builder.build().getHeaders());
    }

    public boolean supports(Type type) {
        return type.equals(Type.REQUEST);
    }
}

ps: Forgive my English, I am still trying to learn it.

bug

Most helpful comment

Ok, it should be fixed. Please wait for the snapshots and try again.

All 11 comments

But TraceRequestHttpHeadersFilter is so strange. Why is its implementation covered instead of append?

What do you mean exactly? Can you create a test or sample that reproduces the issue?

@marcingrzejszczak The input argument is completely ignored in this method in TraceRequestHttpHeadersFilter, so that means that all updated headers, for example the Forwarded header, is removed from this list.

@martinvisser thanks for the issue report, I've managed to reproduce it and fix it. Please wait for the snapshots to be uploaded and double check that everything works fine.

@marcingrzejszczak Thanks for the fix, but I think this isn't completely correct yet.
For example, this is my "input":

[
Cookie:"test=value",
Accept:"*/*",
Accept-Encoding:"gzip,deflate",
User-Agent:"Apache-HttpClient/4.5.6 (Java/11.0.2)",
x-session-id:"397ec5c3-be7c-4473-a427-26327ec3bab0",
x-auth-user:"aaaa",
host:"localhost",
Forwarded:"proto=http;host=localhost;for="127.0.0.1:50243"",
X-Forwarded-For:"127.0.0.1",
X-Forwarded-Proto:"http",
X-Forwarded-Port:"80",
X-Forwarded-Host:"localhost"
]

Then the output is now:

[
Cookie:"test=value", "test=value",
Accept:"*/*", "*/*",
Accept-Encoding:"gzip,deflate", "gzip,deflate",
User-Agent:"Apache-HttpClient/4.5.6 (Java/11.0.2)", "Apache-HttpClient/4.5.6 (Java/11.0.2)",
x-session-id:"397ec5c3-be7c-4473-a427-26327ec3bab0", "397ec5c3-be7c-4473-a427-26327ec3bab0",
x-auth-user:"aaaa", "aaaa",
host:"localhost", "localhost",
Forwarded:"proto=http;host=localhost;for="127.0.0.1:50243"",
X-Forwarded-For:"127.0.0.1",
X-Forwarded-Proto:"http",
X-Forwarded-Port:"80",
X-Forwarded-Host:"localhost",
baggage_session-id:"397ec5c3-be7c-4473-a427-26327ec3bab0",
X-B3-Sampled:"1",
X-B3-TraceId:"62bc0de59f130256",
Connection:"Keep-Alive",
X-B3-SpanId:"d20d1f2d180451dd",
X-B3-ParentSpanId:"39fdbc9844fa9e01",
baggage-session-id:"397ec5c3-be7c-4473-a427-26327ec3bab0"
]

In other words, header values are duplicated.

Ah, I see. Let me reopen it and give it another go ;)

BTW it would be much easier with a sample from your side.

Ok, it should be fixed. Please wait for the snapshots and try again.

That's working perfectly!

This change introduced a new bug. If I have multiple headers with the same name, it discards everything and preserves only the first header.
That happens exactly because of this change:
https://github.com/spring-cloud/spring-cloud-sleuth/commit/1775ec1000d638a61dfcb852a54a8bdf2159ed18#diff-80efc26f63f80d00df56ec6edd649968R59

Can you provide more information or a test case that replicates the issue?

Was this page helpful?
0 / 5 - 0 ratings