Skip to content
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
23 changes: 23 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,29 @@ def response = httpRequest customHeaders: [[maskValue: true, name: 'foo', value
url: 'https://api.github.com/orgs/${orgName}'
----

You can set custom headers with special characters in their names (such as hyphens) using a Map:

[source,groovy]
----
def headerMap = ['my-custom-header-with-hyphen-separator': 'headerValue']
def response = httpRequest headersMap: headerMap,
url: 'https://api.github.com/orgs/${orgName}'
----

Alternatively, you can use the static factory method:

[source,groovy]
----
import jenkins.plugins.http_request.util.HttpRequestNameValuePair

def headers = [
HttpRequestNameValuePair.create('my-custom-header-with-hyphen-separator', 'value1', false),
HttpRequestNameValuePair.create('another-header', 'value2', true) // true to mask the value
]
def response = httpRequest customHeaders: headers,
url: 'https://api.github.com/orgs/${orgName}'
----

You can send ``multipart/form-data`` forms:

[source,groovy]
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/jenkins/plugins/http_request/HttpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -240,6 +245,24 @@
this.customHeaders = customHeaders;
}

/**
* Set custom headers from a Map to support headers with special characters in their names.
* This is an alternative to using the List<HttpRequestNameValuePair> that makes it easier
* to define headers with special characters in the name such as hyphens.
*
* @param headerMap Map of header names to values
*/
@DataBoundSetter
public void setHeadersMap(Map<String, String> headerMap) {
List<HttpRequestNameValuePair> headers = new ArrayList<>();
if (headerMap != null) {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
headers.add(new HttpRequestNameValuePair(entry));
}
}
this.customHeaders = headers;
}

Check warning on line 264 in src/main/java/jenkins/plugins/http_request/HttpRequest.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 257-264 are not covered by tests

public List<HttpRequestFormDataPart> getFormData() {
return formData;
}
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/jenkins/plugins/http_request/HttpRequestStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

Expand Down Expand Up @@ -204,6 +205,24 @@
this.customHeaders = customHeaders;
}

/**
* Set custom headers from a Map to support headers with special characters in their names.
* This is an alternative to using the List&lt;HttpRequestNameValuePair&gt; that makes it easier
* to define headers with special characters in the name such as hyphens.
*
* @param headerMap Map of header names to values
*/
@DataBoundSetter
public void setHeadersMap(Map<String, String> headerMap) {
List<HttpRequestNameValuePair> headers = new ArrayList<>();
if (headerMap != null) {

Check warning on line 218 in src/main/java/jenkins/plugins/http_request/HttpRequestStep.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 218 is only partially covered, one branch is missing
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
headers.add(new HttpRequestNameValuePair(entry));
}
}
this.customHeaders = headers;
}

public List<HttpRequestNameValuePair> getCustomHeaders() {
return customHeaders;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package jenkins.plugins.http_request.util;

import java.io.Serializable;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;

import edu.umd.cs.findbugs.annotations.NonNull;
Expand All @@ -21,7 +23,7 @@
private static final long serialVersionUID = -5179602567301232134L;
private final String name;
private final String value;
private final boolean maskValue;
private boolean maskValue;

@DataBoundConstructor
public HttpRequestNameValuePair(String name, String value, boolean maskValue) {
Expand All @@ -33,6 +35,26 @@
public HttpRequestNameValuePair(String name, String value) {
this(name, value, false);
}

/**
* Constructor that accepts a Map.Entry to support headers with special characters in their names
* @param entry Map.Entry containing the header name and value
*/
public HttpRequestNameValuePair(Map.Entry<String, String> entry) {
this(entry.getKey(), entry.getValue(), false);
}

/**
* Constructor that accepts a header name and value directly
* This allows headers with special characters (like hyphens) to be created more easily
* @param name The header name (can contain special characters)
* @param value The header value
* @param maskValue Whether to mask the value in logs
* @return A new HttpRequestNameValuePair
*/
public static HttpRequestNameValuePair create(String name, String value, boolean maskValue) {
return new HttpRequestNameValuePair(name, value, maskValue);
}

public String getName() {
return name;
Expand All @@ -45,6 +67,11 @@
public boolean getMaskValue() {
return maskValue;
}

@DataBoundSetter
public void setMaskValue(boolean maskValue) {
this.maskValue = maskValue;
}

Check warning on line 74 in src/main/java/jenkins/plugins/http_request/util/HttpRequestNameValuePair.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 73-74 are not covered by tests

@Extension
public static class NameValueParamDescriptor extends Descriptor<HttpRequestNameValuePair> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package jenkins.plugins.http_request;

import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.jvnet.hudson.test.JenkinsRule;

import hudson.model.Result;
import jenkins.plugins.http_request.util.HttpRequestNameValuePair;

import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;

/**
* Test for HttpRequest with headers that contain special characters
*/
public class HttpRequestStepSpecialHeadersTest {

@Rule
public final JenkinsRule j = new JenkinsRule();

@Rule
public ExpectedException thrown = ExpectedException.none();

/**
* Test that we can use headers with special characters in their names
*/
@Test
public void testSpecialCharactersInHeaderNamesUsingMap() throws Exception {
// Create a test pipeline that uses the new setHeadersMap method
String script = "node {\n" +
" def headerMap = ['my-custom-header-with-hyphen-separator': 'test-value']\n" +
" def response = httpRequest url: 'http://example.com', headersMap: headerMap\n" +
" echo \"Response: ${response.content}\"\n" +
"}";

WorkflowJob project = j.createProject(WorkflowJob.class);
project.setDefinition(new CpsFlowDefinition(script, true));

// The actual HTTP request to example.com actually works in the test environment
WorkflowRun run = project.scheduleBuild2(0).get();
j.assertBuildStatusSuccess(run);
j.assertLogContains("my-custom-header-with-hyphen-separator: test-value", run);
}

/**
* Test that we can create headers with special characters using the static factory method
*/
@Test
public void testSpecialCharactersInHeaderNamesUsingCreate() throws Exception {
// Test the static factory method create()
HttpRequestNameValuePair header = HttpRequestNameValuePair.create(
"my-custom-header-with-hyphen-separator",
"test-value",
false);

assertEquals("my-custom-header-with-hyphen-separator", header.getName());
assertEquals("test-value", header.getValue());
assertEquals(false, header.getMaskValue());
}

/**
* Test that we can create headers with special characters using the Map.Entry constructor
*/
@Test
public void testSpecialCharactersInHeaderNamesUsingMapEntry() throws Exception {
// Create a map with a header that contains special characters
Map<String, String> headerMap = new HashMap<>();
headerMap.put("my-custom-header-with-hyphen-separator", "test-value");

// Create a header using the entry from the map
Map.Entry<String, String> entry = headerMap.entrySet().iterator().next();
HttpRequestNameValuePair header = new HttpRequestNameValuePair(entry);

assertEquals("my-custom-header-with-hyphen-separator", header.getName());
assertEquals("test-value", header.getValue());
}
}
Loading