Skip to content

Commit

Permalink
fix(citrusframework#472): Add Http header name ignore case setting
Browse files Browse the repository at this point in the history
Enable/disable header name case-insensitive verification mode
  • Loading branch information
christophd committed Aug 31, 2023
1 parent cc4f660 commit 9f55500
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
14 changes: 14 additions & 0 deletions java/docs/steps-http.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,20 @@ Then expect HTTP response headers
| Content-Type | application/json |
----

==== Header name ignore case

Header names are not case-sensitive per Http specification. This means servers and clients may choose the header name case individually. In order to avoid verification errors when expecting headers in Http the header validation mechanism in Citrus is able to ignore the header name case.

.@Given("^HTTP header name ignore case is (enabled|disabled)$")
[source,gherkin]
----
Given HTTP header name ignore case is enabled
----

This will enable the mode where header name verification is case-insensitive.

You may also use a environment setting `YAKS_HTTP_HEADER_NAME_IGNORE_CASE=true/false` in `yaks-config` to enable/disable the setting for the whole test suite. By default, the setting is disabled so header names are verified with case-sensitive mode.

==== Response body

.@Then("^expect HTTP response body: {body}$")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@

package org.citrusframework.yaks.http;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLContext;

import com.consol.citrus.Citrus;
import com.consol.citrus.CitrusSettings;
Expand Down Expand Up @@ -78,6 +78,7 @@ public class HttpClientSteps implements HttpSteps {
private Map<String, String> responseHeaders = new HashMap<>();
private Map<String, String> requestParams = new HashMap<>();

private boolean headerNameIgnoreCase = HttpSettings.isHeaderNameIgnoreCase();
private Map<String, Object> bodyValidationExpressions = new HashMap<>();

private String requestMessageType;
Expand Down Expand Up @@ -147,6 +148,11 @@ public void configureForkMode(String mode) {
this.forkMode = "enabled".equals(mode);
}

@Given("^HTTP header name ignore case is (enabled|disabled)$")
public void configureHeaderNameIgnoreCase(String mode) {
this.headerNameIgnoreCase = "enabled".equals(mode);
}

@Given("^(?:URL|url) is healthy$")
public void healthCheck() {
waitForHttpUrl(requestUrl);
Expand Down Expand Up @@ -350,7 +356,8 @@ private void sendClientRequest(HttpMessage request) {
private void receiveClientResponse(HttpMessage response) {
HttpClientResponseActionBuilder.HttpMessageBuilderSupport responseBuilder = http().client(httpClient).receive()
.response(response.getStatusCode())
.message(response);
.message(response)
.headerNameIgnoreCase(headerNameIgnoreCase);

responseBuilder.validate(pathExpression().expressions(bodyValidationExpressions));
bodyValidationExpressions.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public class HttpServerSteps implements HttpSteps {
private Map<String, String> responseHeaders = new HashMap<>();
private Map<String, String> requestParams = new HashMap<>();

private boolean headerNameIgnoreCase = HttpSettings.isHeaderNameIgnoreCase();

private Map<String, Object> bodyValidationExpressions = new HashMap<>();

private String requestMessageType;
Expand Down Expand Up @@ -140,6 +142,11 @@ public void setServer(String name) {
}
}

@Given("^HTTP server header name ignore case is (enabled|disabled)$")
public void configureHeaderNameIgnoreCase(String mode) {
this.headerNameIgnoreCase = "enabled".equals(mode);
}

@Given("^HTTP server \"([^\"\\s]+)\" with configuration$")
public void setServerWithProperties(String name, DataTable properties) {
configureServer(properties.asMap(String.class, String.class));
Expand Down Expand Up @@ -356,6 +363,8 @@ public void receiveServerRequest(HttpMessage request) {
requestBuilder = receiveBuilder.post().message(request);
}

requestBuilder.headerNameIgnoreCase(headerNameIgnoreCase);

if (!bodyValidationExpressions.isEmpty()) {
requestBuilder.validate(pathExpression().expressions(bodyValidationExpressions));
bodyValidationExpressions.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public class HttpSettings {
private static final String SECURE_KEYSTORE_PASSWORD_ENV = HTTP_ENV_PREFIX + "SECURE_KEYSTORE_PASSWORD";
private static final String SECURE_KEYSTORE_PASSWORD_DEFAULT = "secret";

private static final String HEADER_NAME_IGNORE_CASE_PROPERTY = HTTP_PROPERTY_PREFIX + "header.name.ignore.case";
private static final String HEADER_NAME_IGNORE_CASE_ENV = HTTP_ENV_PREFIX + "HEADER_NAME_IGNORE_CASE";
private static final String HEADER_NAME_IGNORE_CASE_DEFAULT = "false";

private HttpSettings() {
// prevent instantiation of utility class
}
Expand Down Expand Up @@ -121,4 +125,10 @@ public static String getSslKeyStorePassword() {
System.getenv(SECURE_KEYSTORE_PASSWORD_ENV) != null ? System.getenv(SECURE_KEYSTORE_PASSWORD_ENV) :
SECURE_KEYSTORE_PASSWORD_DEFAULT);
}

public static boolean isHeaderNameIgnoreCase() {
return Boolean.parseBoolean(System.getProperty(HEADER_NAME_IGNORE_CASE_PROPERTY,
System.getenv(HEADER_NAME_IGNORE_CASE_ENV) != null ? System.getenv(HEADER_NAME_IGNORE_CASE_ENV) :
HEADER_NAME_IGNORE_CASE_DEFAULT));
}
}

0 comments on commit 9f55500

Please sign in to comment.