Spring Integration Wrong Host Header

[亡魂溺海] 提交于 2019-12-12 05:49:06

问题


We've been experiencing this weird problem with the request Host header being set as the application's URL. This results to the external system to not handle our requests.

Here's the DEBUG log of apache of the Spring Integration application hosted on localhost:8082. Don't mind the content for now but the Content-Type will be a problem subsequently:

org.apache.http.wire - http-outgoing-0 >> "POST /health HTTP/1.1[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Accept: */*[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "cookie: PHPSESSID=ost897ibh0j7rovf2rudr33c22[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "host: localhost:8082[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "connection: keep-alive[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Cache-Control: no-cache[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Type: application/xml[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "accept-encoding: gzip, deflate[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "user-agent: PostmanRuntime/6.1.6[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Length: 4[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "test"
org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "Content-Type: application/json[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "Transfer-Encoding: chunked[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "Server: Jetty(9.2.z-SNAPSHOT)[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "27[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "{"success":true,"message":"Service up"}"
org.apache.http.headers - http-outgoing-0 << HTTP/1.1 200 OK
org.apache.http.headers - http-outgoing-0 << Content-Type: application/json
org.apache.http.headers - http-outgoing-0 << Transfer-Encoding: chunked
org.apache.http.headers - http-outgoing-0 << Server: Jetty(9.2.z-SNAPSHOT)
org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "0[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "[\r][\n]"

and here's the request done with curl:

curl -v -X POST http://localhost:9292/health
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 9292 (#0)
> POST /health HTTP/1.1
> Host: localhost:9292
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json
< Transfer-Encoding: chunked
< Server: Jetty(9.2.z-SNAPSHOT)

So with Spring Integration org.apache.http.wire - http-outgoing-0 >> "host: localhost:8082[\r][\n]"

and with curl > Host: localhost:9292

We can easily solve the host problem in Spring Integration by setting the header mapper of the outgate: handler.setHeaderMapper(new DefaultHttpHeaderMapper());

org.apache.http.wire - http-outgoing-0 >> "POST /health HTTP/1.1[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Accept: application/json, application/*+json[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Type: text/plain;charset=UTF-8[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Length: 4[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Host: localhost:9292[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "test"

So we were able to solve the problem with the Host header, unfortunately, it seems that the Content-Type set through an enricher has been ignored and has been set to text/plain instead of application/xml.

What seems to be the problem here? I'm assuming this has to do with just using a basic DefaultHttpHeaderMapper.

Here's the flow configuration snippet:

public class BasicIntegrationConfig {

    @Bean
    public MessageChannel basicRequestChannel() {
        return MessageChannels.publishSubscribe().get();
    }

    @Bean
    public MessageChannel basicResponseChannel() {
        return MessageChannels.publishSubscribe().get();
    }

    @Bean
    public MessagingGatewaySupport basicInGate() {
        HttpRequestHandlingMessagingGateway handler = new HttpRequestHandlingMessagingGateway();

        RequestMapping mapping = new RequestMapping();
        mapping.setPathPatterns("api/v1/basic");
        mapping.setMethods(HttpMethod.GET);
        mapping.setProduces(MediaType.APPLICATION_JSON_UTF8_VALUE);
        handler.setRequestMapping(mapping);

        handler.setRequestChannel(basicRequestChannel());
        handler.setReplyChannel(basicResponseChannel());

        return handler;
    }

    @Bean
    public MessageHandler basicOutGate() {
        HttpRequestExecutingMessageHandler handler =
                new HttpRequestExecutingMessageHandler("http://localhost:9292/health");
        handler.setHttpMethod(HttpMethod.POST);
        handler.setExpectedResponseType(BaseResponse.class);
        handler.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
        handler.setHeaderMapper(new DefaultHttpHeaderMapper());
        return handler;
    }

    @Bean
    public IntegrationFlow basicFlow() {
        return (IntegrationFlowDefinition<?> f) -> f
                .channel(basicRequestChannel())
                .log("basic")
                .handle((GenericHandler<Object>) (o, map) -> "test")
                .enrichHeaders(e -> e.header(MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE, true))
                .log("basic")
                .handle(basicOutGate())
                .log("basic")
                .enrichHeaders(e -> e.header(MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE, true))
                .channel(basicResponseChannel());
    }
}

回答1:


Use

DefaultHttpHeaderMapper mapper = DefaultHttpHeaderMapper.outboundMapper();
mapper.setExcludedOutboundStandardRequestHeaderNames(new String[] { "Host" });
handler.setHeaderMapper(mapper);


来源:https://stackoverflow.com/questions/44908154/spring-integration-wrong-host-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!