Skip to content

Commit

Permalink
feat(#1243): Add option to configure disable redirect for HttpClient
Browse files Browse the repository at this point in the history
  • Loading branch information
Thorsten Schlathoelter authored and bbortt committed Oct 29, 2024
1 parent fa33025 commit bab5347
Show file tree
Hide file tree
Showing 14 changed files with 269 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@ public HttpClientBuilder handleCookies(boolean flag) {
return this;
}

/**
* Sets the disabled redirect handling property.
* @param flag
* @return
*/
public HttpClientBuilder disableRedirectHandling(boolean flag) {
endpoint.getEndpointConfiguration().setDisableRedirectHandling(flag);
return this;
}

/**
* Sets the content type.
* @param contentType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.citrusframework.endpoint.AbstractPollableEndpointConfiguration;
import org.citrusframework.endpoint.resolver.DynamicEndpointUriResolver;
Expand Down Expand Up @@ -98,6 +97,11 @@ public class HttpEndpointConfiguration extends AbstractPollableEndpointConfigura
/** Should handle http cookies */
private boolean handleCookies = false;

/**
* Should disable redirect handling
*/
private boolean disableRedirectHandling = false;

/** Default status code returned by http server */
private int defaultStatusCode = HttpStatus.OK.value();

Expand Down Expand Up @@ -319,6 +323,10 @@ public HttpClientBuilder getHttpClient() {
httpClient = HttpClientBuilder.create().useSystemProperties();
}

if (disableRedirectHandling) {
httpClient.disableRedirectHandling();
}

return httpClient;
}

Expand Down Expand Up @@ -396,6 +404,24 @@ public void setHandleCookies(boolean handleCookies) {
this.handleCookies = handleCookies;
}

/**
* Gets the disableRedirectHandling.
*
* @return
*/
public boolean isDisableRedirectHandling() {
return disableRedirectHandling;
}

/**
* Sets the disableRedirectHandling.
*
* @param disableRedirectHandling
*/
public void setDisableRedirectHandling(boolean disableRedirectHandling) {
this.disableRedirectHandling = disableRedirectHandling;
}

/**
* Gets the errorHandler.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@
*/
boolean handleCookies() default false;

/**
* Disbable redirect handling.
* @return
*/
boolean disableRedirectHandling() default false;

/**
* Content type.
* @return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public HttpClient parse(HttpClientConfig annotation, ReferenceResolver reference

builder.defaultAcceptHeader(annotation.defaultAcceptHeader());
builder.handleCookies(annotation.handleCookies());
builder.disableRedirectHandling(annotation.disableRedirectHandling());
builder.charset(annotation.charset());
builder.contentType(annotation.contentType());
builder.pollingInterval(annotation.pollingInterval());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ protected void parseEndpointConfiguration(BeanDefinitionBuilder endpointConfigur
BeanDefinitionParserUtils.setPropertyValue(endpointConfiguration, element.getAttribute("content-type"), "contentType");
BeanDefinitionParserUtils.setPropertyValue(endpointConfiguration, element.getAttribute("polling-interval"), "pollingInterval");
BeanDefinitionParserUtils.setPropertyValue(endpointConfiguration, element.getAttribute("handle-cookies"), "handleCookies");
BeanDefinitionParserUtils.setPropertyValue(endpointConfiguration, element.getAttribute("disable-redirect-handling"), "disableRedirectHandling");

BeanDefinitionParserUtils.setPropertyReference(endpointConfiguration, element.getAttribute("error-handler"), "errorHandler");
if (element.hasAttribute("error-strategy")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<xs:attribute name="content-type" type="xs:string"/>
<xs:attribute name="default-accept-header" type="xs:boolean"/>
<xs:attribute name="handle-cookies" type="xs:boolean"/>
<xs:attribute name="disable-redirect-handling" type="xs:boolean"/>
<xs:attribute name="interceptors" type="xs:string"/>
<xs:attribute name="binary-media-types" type="xs:string"/>
<xs:attribute name="error-handler" type="xs:string"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public class HttpClientConfigParserTest extends AbstractTestNGUnitTest {
charset="ISO-8859-1",
defaultAcceptHeader=false,
handleCookies=true,
disableRedirectHandling = true,
timeout=10000L,
errorStrategy = ErrorHandlingStrategy.THROWS_EXCEPTION,
errorHandler = "errorHandler",
Expand Down Expand Up @@ -161,6 +162,7 @@ public void testHttpClientParser() {
Assert.assertEquals(httpClient2.getEndpointConfiguration().getTimeout(), 10000L);
Assert.assertFalse(httpClient2.getEndpointConfiguration().isDefaultAcceptHeader());
Assert.assertTrue(httpClient2.getEndpointConfiguration().isHandleCookies());
Assert.assertTrue(httpClient2.getEndpointConfiguration().isDisableRedirectHandling());
Assert.assertEquals(httpClient2.getEndpointConfiguration().getErrorHandlingStrategy(), ErrorHandlingStrategy.THROWS_EXCEPTION);
Assert.assertEquals(httpClient2.getEndpointConfiguration().getErrorHandler(), errorHandler);
Assert.assertEquals(httpClient2.getEndpointConfiguration().getBinaryMediaTypes().size(), 2L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.citrusframework.http.config.xml;

import java.util.Map;

import org.citrusframework.TestActor;
import org.citrusframework.http.client.HttpClient;
import org.citrusframework.http.client.HttpResponseErrorHandler;
Expand Down Expand Up @@ -57,6 +56,7 @@ public void testHttpClientParser() {
Assert.assertEquals(httpClient.getEndpointConfiguration().getCorrelator().getClass(), DefaultMessageCorrelator.class);
Assert.assertEquals(httpClient.getEndpointConfiguration().getTimeout(), 5000L);
Assert.assertFalse(httpClient.getEndpointConfiguration().isHandleCookies());
Assert.assertFalse(httpClient.getEndpointConfiguration().isDisableRedirectHandling());

// 2nd message sender
httpClient = clients.get("httpClient2");
Expand All @@ -72,6 +72,7 @@ public void testHttpClientParser() {
Assert.assertEquals(httpClient.getEndpointConfiguration().getTimeout(), 10000L);
Assert.assertFalse(httpClient.getEndpointConfiguration().isDefaultAcceptHeader());
Assert.assertTrue(httpClient.getEndpointConfiguration().isHandleCookies());
Assert.assertTrue(httpClient.getEndpointConfiguration().isDisableRedirectHandling());
Assert.assertEquals(httpClient.getEndpointConfiguration().getErrorHandlingStrategy(), ErrorHandlingStrategy.THROWS_EXCEPTION);
Assert.assertEquals(httpClient.getEndpointConfiguration().getErrorHandler(), beanDefinitionContext.getBean("errorHandler"));
Assert.assertEquals(httpClient.getEndpointConfiguration().getBinaryMediaTypes().size(), 2L);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright the original author or 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 org.citrusframework.http.integration;

import org.citrusframework.annotations.CitrusTestSource;
import org.citrusframework.common.TestLoader;
import org.citrusframework.testng.spring.TestNGCitrusSpringSupport;
import org.testng.annotations.Test;

@Test
public class HttpClientWithRedirectIT extends TestNGCitrusSpringSupport {

@CitrusTestSource(type = TestLoader.SPRING, name = "HttpClientWithRedirectIT")
public void testHttpClientWithRedirect() {}

@CitrusTestSource(type = TestLoader.SPRING, name = "HttpClientWithRedirectDisabledIT")
public void testHttpClientWithRedirectDisabled() {}
}
15 changes: 15 additions & 0 deletions endpoints/citrus-http/src/test/resources/citrus-context.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@
context-config-location="classpath:org/citrusframework/http/citrus-http-servlet.xml"
resource-base="src/test/resources"/>

<citrus-http:client id="helloHttpClientWithRedirect"
request-url="http://localhost:14080/hello"
timeout="5000"/>

<citrus-http:client id="helloHttpClientWithRedirectDisabled"
request-url="http://localhost:14080/hello"
disable-redirect-handling="true"
timeout="5000"/>

<citrus-http:server id="helloHttpServerWithRedirect"
port="14080"
auto-start="true"
context-config-location="classpath:org/citrusframework/http/citrus-http-with-redirect-servlet.xml"
resource-base="src/test/resources"/>

<citrus-http:client id="echoHttpClient"
request-url="http://localhost:12080/echo"
handle-cookies="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<description>Contains the root context. Gets loaded via ContextLoaderListener in web.xml</description>

<context:annotation-config/>

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<util:list id="converters">
<bean class="org.citrusframework.http.message.DelegatingHttpEntityMessageConverter"/>
</util:list>
</property>
</bean>

<!-- Controller for handling rest requests -->
<bean class="org.citrusframework.http.controller.HttpMessageController">
<property name="endpointAdapter">
<bean class="org.citrusframework.endpoint.adapter.StaticResponseEndpointAdapter">
<property name="messageHeader">
<map>
<entry key="citrus_http_status_code" value="302"/>
<entry key="Location" value="http://localhost:11080/hello"/>
<entry key="CorrelationId" value="1000000001"/>
</map>
</property>
</bean>
</property>
</bean>

</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
timeout="10000"
default-accept-header="false"
handle-cookies="true"
disable-redirect-handling="true"
error-strategy="throwsException"
error-handler="errorHandler"
message-converter="messageConverter"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<spring:beans xmlns="http://www.citrusframework.org/schema/testcase"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:http="http://www.citrusframework.org/schema/http/testcase"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.citrusframework.org/schema/testcase http://www.citrusframework.org/schema/testcase/citrus-testcase.xsd
http://www.citrusframework.org/schema/http/testcase http://www.citrusframework.org/schema/http/testcase/citrus-http-testcase.xsd">

<testcase name="HttpClientWithRedirectDisabledIT">
<meta-info>
<author>Thorsten Schlathoelter</author>
<creationdate>2024-10-28</creationdate>
<status>FINAL</status>
</meta-info>

<description>
Tests sending messages to an HTTP server instance that issues a redirect.
The HTTP client used for the request has redirectDisabled enabled, preventing
automatic redirection. This allows direct assertion of the response.
</description>

<variables>
<variable name="correlationId" value="1000000001"></variable>
<variable name="messageId" value="@randomNumber(10)@"></variable>
<variable name="user" value="User"></variable>
</variables>

<actions>
<echo>
<message>Test: Send Http request and receive redirect</message>
</echo>

<http:send-request client="helloHttpClientWithRedirectDisabled">
<http:POST>
<http:headers>
<http:header name="Operation" value="sayHello"/>
<http:header name="CorrelationId" value="${correlationId}"/>
</http:headers>
<http:body>
<http:data>
<![CDATA[
<HelloRequest xmlns="http://citrusframework.org/schemas/samples/HelloService.xsd">
<MessageId>${messageId}</MessageId>
<CorrelationId>${correlationId}</CorrelationId>
<User>${user}</User>
<Text>Hello Citrus</Text>
</HelloRequest>
]]>
</http:data>
</http:body>
</http:POST>
</http:send-request>

<http:receive-response client="helloHttpClientWithRedirectDisabled">
<http:headers status="302" reason-phrase="FOUND" version="HTTP/1.1">
<http:header name="Location" value="http://localhost:11080/hello"/>
</http:headers>
</http:receive-response>

</actions>
</testcase>
</spring:beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<spring:beans xmlns="http://www.citrusframework.org/schema/testcase"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:http="http://www.citrusframework.org/schema/http/testcase"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.citrusframework.org/schema/testcase http://www.citrusframework.org/schema/testcase/citrus-testcase.xsd
http://www.citrusframework.org/schema/http/testcase http://www.citrusframework.org/schema/http/testcase/citrus-http-testcase.xsd">

<testcase name="HttpClientWithRedirectIT">
<meta-info>
<author>Thorsten Schlathoelter</author>
<creationdate>2024-10-28</creationdate>
<status>FINAL</status>
</meta-info>

<description>
Tests sending messages to an HTTP server instance that issues a redirect.
By default, the HTTP client follows the redirect, which means the original
response is not stored in the message store for evaluation. Receive-response
therefore throws an error. Therefore, the receive-response action below is
asserted.
</description>

<variables>
<variable name="correlationId" value="1000000001"></variable>
<variable name="messageId" value="@randomNumber(10)@"></variable>
<variable name="user" value="User"></variable>
</variables>

<actions>
<echo>
<message>Test: Send Http request and fail on receive because of redirect</message>
</echo>

<http:send-request client="helloHttpClientWithRedirect">
<http:POST>
<http:headers>
<http:header name="Operation" value="sayHello"/>
<http:header name="CorrelationId" value="${correlationId}"/>
</http:headers>
<http:body>
<http:data>
<![CDATA[
<HelloRequest xmlns="http://citrusframework.org/schemas/samples/HelloService.xsd">
<MessageId>${messageId}</MessageId>
<CorrelationId>${correlationId}</CorrelationId>
<User>${user}</User>
<Text>Hello Citrus</Text>
</HelloRequest>
]]>
</http:data>
</http:body>
</http:POST>
</http:send-request>

<assert exception="org.citrusframework.exceptions.CitrusRuntimeException">
<when>
<http:receive-response client="helloHttpClientWithRedirect">
<http:headers status="302" reason-phrase="FOUND" version="HTTP/1.1">
<http:header name="Location" value="http://localhost:11080/hello"/>
</http:headers>
</http:receive-response>
</when>
</assert>

</actions>
</testcase>
</spring:beans>

0 comments on commit bab5347

Please sign in to comment.