Skip to content

Conversation

@strangelookingnerd
Copy link
Contributor

@strangelookingnerd strangelookingnerd commented Feb 20, 2025

Replaces outdated httpclient4 with the successor httpclient5.

I'm well aware that this is a quite large changeset however I hope that there is still interest in this PR and it will be reviewed.
If there are any questions, please do not hesitate to ping me.

Testing done

mvn clean verify and some manual testing.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

@strangelookingnerd strangelookingnerd requested a review from a team as a code owner February 20, 2025 10:25
}
}

private void configureTimeoutAndSsl(HttpClientBuilder clientBuilder) throws NoSuchAlgorithmException, KeyManagementException {

Check warning

Code scanning / Jenkins Security Scan

Jenkins: Generally unsafe method calls Warning

Potentially unsafe invocation of SSLContext#init
}
return items;
}
public ListBoxModel doFillResponseHandleItems() {

Check warning

Code scanning / Jenkins Security Scan

Stapler: Missing permission check Warning

Potential missing permission check in DescriptorImpl#doFillResponseHandleItems
}
return items;
}
public ListBoxModel doFillResponseHandleItems() {

Check warning

Code scanning / Jenkins Security Scan

Stapler: Missing POST/RequirePOST annotation Warning

Potential CSRF vulnerability: If DescriptorImpl#doFillResponseHandleItems connects to user-specified URLs, modifies state, or is expensive to run, it should be annotated with @POST or @RequirePOST
@QueryParameter String url) {
return HttpRequest.DescriptorImpl.fillAuthenticationItems(project, url);
}
public ListBoxModel doFillProxyAuthenticationItems(@AncestorInPath Item project,

Check warning

Code scanning / Jenkins Security Scan

Stapler: Missing POST/RequirePOST annotation Warning

Potential CSRF vulnerability: If DescriptorImpl#doFillProxyAuthenticationItems connects to user-specified URLs, modifies state, or is expensive to run, it should be annotated with @POST or @RequirePOST
}

public FormValidation doCheckValidResponseCodes(@QueryParameter String value) {
public FormValidation doCheckValidResponseCodes(@QueryParameter String value) {

Check warning

Code scanning / Jenkins Security Scan

Stapler: Missing permission check Warning

Potential missing permission check in DescriptorImpl#doCheckValidResponseCodes
}

public FormValidation doCheckValidResponseCodes(@QueryParameter String value) {
public FormValidation doCheckValidResponseCodes(@QueryParameter String value) {

Check warning

Code scanning / Jenkins Security Scan

Stapler: Missing POST/RequirePOST annotation Warning

Potential CSRF vulnerability: If DescriptorImpl#doCheckValidResponseCodes connects to user-specified URLs, modifies state, or is expensive to run, it should be annotated with @POST or @RequirePOST
private static final long serialVersionUID = 4818288270720177069L;

private final String keyName;
private final String keyName;

Check warning

Code scanning / Jenkins Security Scan

Jenkins: Plaintext password storage Warning

Field should be reviewed whether it stores a password and is serialized to disk: keyName
private final String keyName;
@Serial
private static final long serialVersionUID = -4370238820437831639L;
private final String keyName;

Check warning

Code scanning / Jenkins Security Scan

Jenkins: Plaintext password storage Warning

Field should be reviewed whether it stores a password and is serialized to disk: keyName
@strangelookingnerd
Copy link
Contributor Author

Jenkins Security Scan alerts are unrelated to these changes and should be adressed in a separate PR.

@gounthar
Copy link
Contributor

It looks like the build failure has nothing to do with your code modification:
10:19:45 ExecutionException The forked VM terminated without properly saying goodbye. VM crash or System.exit called?

* Migrate imports, classes and methods
* Reduce usage of deprecated classes and methods
* Minor code cleanup
@strangelookingnerd
Copy link
Contributor Author

@jenkinsci/http-request-plugin-developers Kindly requesting a review.

@MarkEWaite
Copy link
Contributor

@jenkinsci/http-request-plugin-developers Kindly requesting a review.

I'm the only active maintainer of this plugin and I'm deeply involved in other activities that are higher priority for me and for Jenkins. It will likely be several months before I'm able to review this.

# Conflicts:
#	src/main/java/jenkins/plugins/http_request/HttpRequestExecution.java
@gounthar gounthar merged commit fcc6528 into jenkinsci:master Aug 12, 2025
17 checks passed
@dgonz782
Copy link

In v1.20 of this plugin, I was able to use GitHub App credentials.
With this change in v1.21, I'm no longer able to do so:

19:37:38  HttpMethod: GET
19:37:38  URL: https://github.<ent>.com/api/v3/repos/<org>/<repo>/pulls/2755
19:37:38  Using authentication: GHES-Jenkins-App
19:37:38  Response Code: 404
Found unhandled java.lang.IllegalStateException exception:
hudson.AbortException: Fail: Status code 404 is not in the accepted range: 100:399 while calling https://github.<ent>.com/api/v3/repos/<org>/<repo>/pulls/2755
	PluginClassLoader for http_request//jenkins.plugins.http_request.HttpRequestExecution.call(HttpRequestExecution.java:294)
	PluginClassLoader for http_request//jenkins.plugins.http_request.HttpRequestStep$Execution.run(HttpRequestStep.java:408)
	PluginClassLoader for http_request//jenkins.plugins.http_request.HttpRequestStep$Execution.run(HttpRequestStep.java:384)
	PluginClassLoader for workflow-step-api//org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:49)
	java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	java.base/java.lang.Thread.run(Unknown Source)

@MarkEWaite
Copy link
Contributor

In v1.20 of this plugin, I was able to use GitHub App credentials.

@strangelookingnerd would you be willing to investigate this? I'd rather not revert back to httpclient 4 after all your good work to make the switch.

@strangelookingnerd
Copy link
Contributor Author

@strangelookingnerd would you be willing to investigate this? I'd rather not revert back to httpclient 4 after all your good work to make the switch.

I can give it a shot.

@dgonz782 Would you be able to share some more details so I could create a reproducible test case? The pipeline script you are using or similar would help solving this issue faster.

@dgonz782
Copy link

dgonz782 commented Oct 23, 2025

@strangelookingnerd - turns out the 404 err was due to an extra / in the constructed api url from clone url.
v1.20 auto-fixed this, but v1.21 doesn't. After removing the extra /, GH App cred works with this plugin.
My apologies for the confusion.

def prData = httpRequest (
   httpMode: 'GET',
   authentication: config.gitHttpsCredential,
-  url: getRepoApiUrl(config.repos.<repo>, "/pulls/${env.CHANGE_ID}")
+  url: getRepoApiUrl(config.repos.<repo>, "pulls/${env.CHANGE_ID}")
)

A url with // worked in v1.20, but doesn't in v1.21:
url: https://HOSTNAME/api/v3/repos/OWNER/REPO//pulls/1234

@strangelookingnerd
Copy link
Contributor Author

According to RFC2396 a double-slash is not a allowed in the path section of a URI. The //sequence has a defined meaning in the URI, it denotes the authority component (server). See RFC2396, sections 3.2, 3.4).

It appears httpclient4 has had a different default behavior when it comes to normalizing URI compared to httpclient5.
While I assume that there are ways to workaround and restore the old behavior, I don't think that it would be correct from a technical standpoint.

@MarkEWaite WDYT?

@MarkEWaite
Copy link
Contributor

there are ways to workaround and restore the old behavior, I don't think that it would be correct from a technical standpoint.

I agree. I think that we should accept that this new behavior is the more correct behavior.

sgscheffler added a commit to sgscheffler/http-request-plugin that referenced this pull request Nov 12, 2025
… 5 minutes

When the timeout parameter is not provided or set to 0 (documented as
'no timeout'), httpclient5 was using its default 5-minute timeout instead.

This fixes the regression introduced in v1.22 during the httpclient5
migration (PR jenkinsci#197) by explicitly setting timeout to DISABLED when
timeout <= 0, restoring the documented behavior.
MarkEWaite added a commit that referenced this pull request Nov 13, 2025
#225)

* Fix JENKINS-76283: httpRequest ignores default timeout 0 and enforces 5 minutes

When the timeout parameter is not provided or set to 0 (documented as
'no timeout'), httpclient5 was using its default 5-minute timeout instead.

This fixes the regression introduced in v1.22 during the httpclient5
migration (PR #197) by explicitly setting timeout to DISABLED when
timeout <= 0, restoring the documented behavior.

* Reduce white space diffs

---------

Co-authored-by: Mark Waite <[email protected]>
@Khaos66
Copy link

Khaos66 commented Nov 25, 2025

@strangelookingnerd I'm afraid I have a regression to report, too.
Starting from v1.21 this requests fails with 403

def response = httpRequest acceptType: 'APPLICATION_JSON',
                              url: "${env.API_URL}api/call/${callno}/branch",
                              customHeaders: [[name: 'X-API-KEY', value: env.API_KEY]],
                              httpMode: 'POST',
                              formData: [[body: "${branch}", contentType: 'text/plain', name: 'Branch']],
                              ignoreSslErrors: true,
                              validResponseCodes: '200,404'

Any idea?
Downgrade to v1.20 worked for now

@strangelookingnerd
Copy link
Contributor Author

@Khaos66 Please have a look at https://issues.jenkins.io/browse/JENKINS-76280 and see if the your problem can be fixed by the incremental plugin build I linked in there. At least from the error message it seems to be of similar nature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants