Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rest-connector): Return always an array for set cookie headers #4202

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ public HttpCommonResult execute(
.execute(
apacheRequest,
new HttpCommonResultResponseHandler(
executionEnvironment,
request.isStoreResponse(),
request.getGroupSetCookieHeaders()));
executionEnvironment, request.isStoreResponse()));
if (HttpStatusHelper.isError(result.status())) {
throw ConnectorExceptionMapper.from(result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,20 @@ public class HttpCommonResultResponseHandler

private final boolean isStoreResponseSelected;

private final boolean groupSetCookieHeaders;

public HttpCommonResultResponseHandler(
@Nullable ExecutionEnvironment executionEnvironment,
boolean isStoreResponseSelected,
boolean groupSetCookieHeaders) {
@Nullable ExecutionEnvironment executionEnvironment, boolean isStoreResponseSelected) {
this.executionEnvironment = executionEnvironment;
this.isStoreResponseSelected = isStoreResponseSelected;
this.fileResponseHandler =
new FileResponseHandler(executionEnvironment, isStoreResponseSelected);
this.groupSetCookieHeaders = groupSetCookieHeaders;
}

@Override
public HttpCommonResult handleResponse(ClassicHttpResponse response) {
int code = response.getCode();
String reason = response.getReasonPhrase();
Map<String, Object> headers =
HttpCommonResultResponseHandler.formatHeaders(
response.getHeaders(), this.groupSetCookieHeaders);
HttpCommonResultResponseHandler.formatHeaders(response.getHeaders());

if (response.getEntity() != null) {
try (InputStream content = response.getEntity().getContent()) {
Expand All @@ -90,23 +84,20 @@ public HttpCommonResult handleResponse(ClassicHttpResponse response) {
return new HttpCommonResult(code, headers, null, reason);
}

private static Map<String, Object> formatHeaders(
Header[] headersArray, Boolean groupSetCookieHeaders) {
private static Map<String, Object> formatHeaders(Header[] headersArray) {
return Arrays.stream(headersArray)
.collect(
Collectors.toMap(
Header::getName,
header -> {
if (groupSetCookieHeaders && header.getName().equalsIgnoreCase("Set-Cookie")) {
if (header.getName().equalsIgnoreCase("Set-Cookie")) {
return new ArrayList<String>(List.of(header.getValue()));
} else {
return header.getValue();
}
},
(existingValue, newValue) -> {
if (groupSetCookieHeaders
&& existingValue instanceof List
&& newValue instanceof List) {
if (existingValue instanceof List && newValue instanceof List) {
((List<String>) existingValue).add(((List<String>) newValue).getFirst());
}
return existingValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,6 @@ public class HttpCommonRequest {
optional = true)
private String skipEncoding;

@TemplateProperty(
label = "Group set-cookie headers to a list",
description =
"Group incoming headers with same name into a List to support <a href=\"https://datatracker.ietf.org/doc/html/rfc6265\">multiple Set-Cookie headers</a>.",
type = TemplateProperty.PropertyType.Hidden,
feel = Property.FeelMode.disabled,
group = "endpoint",
optional = true)
private String groupSetCookieHeaders;

public Object getBody() {
return body;
}
Expand Down Expand Up @@ -166,14 +156,6 @@ public void setSkipEncoding(final String skipEncoding) {
this.skipEncoding = skipEncoding;
}

public boolean getGroupSetCookieHeaders() {
return Objects.equals(groupSetCookieHeaders, "true");
}

public void setGroupSetCookieHeaders(final String groupSetCookieHeaders) {
this.groupSetCookieHeaders = groupSetCookieHeaders;
}

public boolean hasAuthentication() {
return authentication != null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.camunda.document.store.DocumentCreationRequest;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.hc.core5.http.ContentType;
Expand Down Expand Up @@ -200,8 +201,7 @@ public void shouldReturn200WithBody_whenPostRequest(
// then
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(200);
assertThat(result.headers()).contains(Map.entry("Set-Cookie", "key=value"));
assertThat(result.headers()).doesNotContain(Map.entry("Set-Cookie", "key2=value2"));
assertThat(result.headers()).containsEntry("Set-Cookie", List.of("key=value", "key2=value2"));
JSONAssert.assertEquals(
"{\"responseKey1\":\"value1\",\"responseKey2\":40,\"responseKey3\":null}",
objectMapper.writeValueAsString(result.body()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,25 +602,21 @@ public void shouldReturn200WithoutBody_whenEmptyGet(WireMockRuntimeInfo wmRuntim

private static Stream<Arguments> provideTestDataForHeaderTest() {
return Stream.of(
Arguments.of("Set-Cookie", "false", false, "Test-Value-1"),
Arguments.of("Set-Cookie", "true", true, List.of("Test-Value-1", "Test-Value-2")),
Arguments.of("other-than-set-cookie", "false", false, "Test-Value-1"),
Arguments.of("other-than-set-cookie", "true", false, "Test-Value-1"));
Arguments.of("Set-Cookie", true, List.of("Test-Value-1", "Test-Value-2")),
Arguments.of("other-than-set-cookie", false, "Test-Value-1"));
}

@ParameterizedTest
@MethodSource("provideTestDataForHeaderTest")
public void shouldReturn200_whenDuplicatedHeadersAsListDisabled(
String headerKey,
String groupSetCookieHeaders,
Boolean expectedDoesReturnList,
Object expectedValue,
WireMockRuntimeInfo wmRuntimeInfo) {
stubFor(get("/path").willReturn(ok().withHeader(headerKey, "Test-Value-1", "Test-Value-2")));
HttpCommonRequest request = new HttpCommonRequest();
request.setMethod(HttpMethod.GET);
request.setUrl(wmRuntimeInfo.getHttpBaseUrl() + "/path");
request.setGroupSetCookieHeaders(groupSetCookieHeaders);
HttpCommonResult result = customApacheHttpClient.execute(request);
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(200);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ public class HttpCommonResultResponseHandlerTest {
@Test
public void shouldHandleJsonResponse_whenCloudFunctionDisabled() throws Exception {
// given
HttpCommonResultResponseHandler handler =
new HttpCommonResultResponseHandler(null, false, false);
HttpCommonResultResponseHandler handler = new HttpCommonResultResponseHandler(null, false);
ClassicHttpResponse response = new BasicClassicHttpResponse(200);
Header[] headers = new Header[] {new BasicHeader("Content-Type", "application/json")};
response.setHeaders(headers);
Expand All @@ -56,8 +55,7 @@ public void shouldHandleJsonResponse_whenCloudFunctionDisabled() throws Exceptio
@Test
public void shouldHandleTextResponse_whenCloudFunctionDisabled() throws Exception {
// given
HttpCommonResultResponseHandler handler =
new HttpCommonResultResponseHandler(null, false, false);
HttpCommonResultResponseHandler handler = new HttpCommonResultResponseHandler(null, false);
ClassicHttpResponse response = new BasicClassicHttpResponse(200);
Header[] headers = new Header[] {new BasicHeader("Content-Type", "text/plain")};
response.setHeaders(headers);
Expand All @@ -78,8 +76,7 @@ public void shouldHandleTextResponse_whenCloudFunctionDisabled() throws Exceptio
public void shouldHandleJsonResponse_whenCloudFunctionEnabled() throws Exception {
// given
HttpCommonResultResponseHandler handler =
new HttpCommonResultResponseHandler(
new ExecutionEnvironment.SaaSCluster(null), false, false);
new HttpCommonResultResponseHandler(new ExecutionEnvironment.SaaSCluster(null), false);
ClassicHttpResponse response = new BasicClassicHttpResponse(201);
Header[] headers = new Header[] {new BasicHeader("Content-Type", "application/json")};
response.setHeaders(headers);
Expand All @@ -104,8 +101,7 @@ public void shouldHandleJsonResponse_whenCloudFunctionEnabled() throws Exception
public void shouldHandleError_whenCloudFunctionEnabled() throws Exception {
// given
HttpCommonResultResponseHandler handler =
new HttpCommonResultResponseHandler(
new ExecutionEnvironment.SaaSCluster(null), false, false);
new HttpCommonResultResponseHandler(new ExecutionEnvironment.SaaSCluster(null), false);
ClassicHttpResponse response = new BasicClassicHttpResponse(500);
Header[] headers =
new Header[] {
Expand Down Expand Up @@ -134,8 +130,7 @@ public void shouldHandleError_whenCloudFunctionEnabled() throws Exception {
public void shouldHandleJsonAsTextResponse_whenCloudFunctionEnabled() throws Exception {
// given
HttpCommonResultResponseHandler handler =
new HttpCommonResultResponseHandler(
new ExecutionEnvironment.SaaSCluster(null), false, false);
new HttpCommonResultResponseHandler(new ExecutionEnvironment.SaaSCluster(null), false);
ClassicHttpResponse response = new BasicClassicHttpResponse(201);
Header[] headers = new Header[] {new BasicHeader("Content-Type", "application/json")};
response.setHeaders(headers);
Expand Down
17 changes: 3 additions & 14 deletions connectors/http/rest/element-templates/http-json-connector.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,14 @@
},
"type" : "Dropdown",
"choices" : [ {
"name" : "DELETE",
"value" : "DELETE"
}, {
"name" : "POST",
"value" : "POST"
}, {
"name" : "GET",
"value" : "GET"
}, {
"name" : "DELETE",
"value" : "DELETE"
}, {
"name" : "PATCH",
"value" : "PATCH"
Expand Down Expand Up @@ -413,17 +413,6 @@
"type" : "zeebe:input"
},
"type" : "Hidden"
}, {
"id" : "groupSetCookieHeaders",
"label" : "Group set-cookie headers to a list",
"description" : "Group incoming headers with same name into a List to support <a href=\"https://datatracker.ietf.org/doc/html/rfc6265\">multiple Set-Cookie headers</a>.",
"optional" : true,
"group" : "endpoint",
"binding" : {
"name" : "groupSetCookieHeaders",
"type" : "zeebe:input"
},
"type" : "Hidden"
}, {
"id" : "connectionTimeoutInSeconds",
"label" : "Connection timeout in seconds",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,14 @@
},
"type" : "Dropdown",
"choices" : [ {
"name" : "DELETE",
"value" : "DELETE"
}, {
"name" : "POST",
"value" : "POST"
}, {
"name" : "GET",
"value" : "GET"
}, {
"name" : "DELETE",
"value" : "DELETE"
}, {
"name" : "PATCH",
"value" : "PATCH"
Expand Down Expand Up @@ -418,17 +418,6 @@
"type" : "zeebe:input"
},
"type" : "Hidden"
}, {
"id" : "groupSetCookieHeaders",
"label" : "Group set-cookie headers to a list",
"description" : "Group incoming headers with same name into a List to support <a href=\"https://datatracker.ietf.org/doc/html/rfc6265\">multiple Set-Cookie headers</a>.",
"optional" : true,
"group" : "endpoint",
"binding" : {
"name" : "groupSetCookieHeaders",
"type" : "zeebe:input"
},
"type" : "Hidden"
}, {
"id" : "connectionTimeoutInSeconds",
"label" : "Connection timeout in seconds",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"writeTimeoutInSeconds",
"body",
"storeResponse",
"groupSetCookieHeaders"
},
type = HttpJsonFunction.TYPE)
@ElementTemplate(
Expand Down