Skip to content

Add HttpClient5 sampler implementation with HTTP/2 support - #6742

Open
andreaslind01 wants to merge 24 commits into
apache:masterfrom
andreaslind01:httpclient5_http2
Open

Add HttpClient5 sampler implementation with HTTP/2 support#6742
andreaslind01 wants to merge 24 commits into
apache:masterfrom
andreaslind01:httpclient5_http2

Conversation

@andreaslind01

Copy link
Copy Markdown
Contributor

Description

This PR adds a new HTTP sampler implementation, HttpClient5, based on Apache HttpComponents HttpClient 5.x, and introduces a configurable HTTP Version setting (HTTP/1.1 / HTTP/2) for both the HttpClient5 and the Java implementation.

Main changes:

  • New HTTPHC5Impl (HTTPSamplerFactory.IMPL_HTTP_CLIENT5, selectable as HttpClient5 in the GUI and in JMX files):
    • Classic (blocking) client for HTTP/1.1 and an async H2 client for HTTP/2, selected via HttpVersionPolicy (FORCE_HTTP_1 / NEGOTIATE), with automatic fallback to HTTP/1.1 when the server does not offer h2 via ALPN.
    • Per-thread client caching keyed by target/proxy/timeouts/local address/version policy.
    • Support for connect & response timeouts, proxies (incl. proxy authentication), AuthManager (BASIC/DIGEST, pre-emptive BASIC), CacheManager (conditional requests via If-Modified-Since / If-None-Match), CookieManager, DNSCacheManager, response decompression (gzip/deflate/brotli), and retry handling.
    • Correct population of SampleResult metrics: sentBytes, connectTime (measured for both HTTP/1.1 and HTTP/2, including TLS), latency, headers and response code/message.
  • HTTPJavaImpl: HTTP/2 support via the JDK java.net.http.HttpClient when HTTP/2 is selected, including caching, proxies, user authentication, sentBytes accounting, connect-time measurement, reason-phrase derivation (HTTP/2 has no reason phrase) and preservation of Authorization / Proxy-Authorization headers.
  • New sampler property HTTPSampler.httpVersion (HTTPSamplerBaseSchema.httpVersion, getter/setter on HTTPSamplerBase) with a new combo box in HTTP Request and HTTP Request Defaults (http_version resource key added to all messages_*.properties).
  • CacheManager: new overloads for HC5 (ClassicHttpRequest / ClassicHttpResponse / org.apache.hc.core5.http.Header[]) and for the JDK java.net.http.HttpResponse.
  • Property httpclient.version re-purposed as the default HTTP version (HTTP/1.1 | HTTP/2) used when the sampler's HTTP Version field is empty.
  • Dependencies: httpclient5 and httpcore5 added to src/protocol/http and to the third-party BOM (httpcore5:5.3.4).
  • Documentation updated: component_reference.xml, properties_reference.xml, get-started.xml, bin/jmeter.properties.

Motivation and Context

JMeter's HTTP samplers currently only support HTTP/1.1: the HttpClient4 implementation is built on the HttpComponents 4.x line, which will not receive HTTP/2 support, and the Java implementation used the legacy HttpURLConnection. Modern web applications and APIs are increasingly served over HTTP/2, so load tests against them either could not be executed at all or did not represent realistic client behaviour (multiplexing, HPACK header compression, single connection per origin).

This change gives users a supported migration path to HttpComponents 5.x and makes it possible to run load tests over HTTP/2 — either with the fully featured HttpClient5 implementation or, for lightweight scenarios, with the JDK client in the Java implementation. Existing test plans are unaffected: HttpClient4 remains the default and an empty HTTP Version falls back to the previous HTTP/1.1 behaviour.

Fixes:

How Has This Been Tested?

  • New unit/integration tests (34 tests, all green):
    • TestHTTPHC5Features (16 tests): version selection and precedence (sampler value vs. httpclient.version vs. unsupported value), HTTP/2 usage, fallback to HTTP/1.1 when the server does not support h2, HTTP/2 via proxy, sentBytes for GET/POST, conditional requests through CacheManager, BASIC credentials from AuthManager, proxy authentication, and connectTime for HTTP/1.1 and HTTP/2.
    • TestHTTPJavaFeatures (~16 tests): version selection, HTTP/2 requests (incl. via proxy), response message / reason-phrase handling for HTTP/2, sentBytes for GET/POST in both versions, Authorization header from the HeaderManager, and connectTime for HTTP/1.1, HTTP/2 plaintext and HTTP/2 over TLS.
    • TestHTTPSamplerFactory: creation and lookup of the new HttpClient5 implementation, plus the unchanged behaviour for the existing aliases.
    • The tests run against locally started embedded HTTP/1.1, HTTP/2 (h2c and h2 over TLS) and proxy servers, so no external services are required.
  • ./gradlew classes style — compiles cleanly and reports no style/checkstyle/autostyle violations.
  • The existing src:protocol:http test suite (including JMeterTest, extended by httpVersion in the ignored-properties list) still passes.
  • Manual verification in the JMeter GUI: the new HTTP Version combo box in HTTP Request and HTTP Request Defaults is saved/restored correctly in JMX files, and requests against an HTTP/2 endpoint are reported as HTTP/2 in the View Results Tree.
  • Test environment: Windows, JDK 21 toolchain, Gradle build JMeter 6.0.0-SNAPSHOT.

Screenshots (if appropriate):

image

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

  • My code follows the code style of this project.
  • I have updated the documentation accordingly.

…ng, caching, proxies, and user authentication
…and improve fallback handling with new tests
…ts, including HTTP/2, with corresponding unit tests
…ers (`Authorization`, `Proxy-Authorization`) and adding unit tests for validation

@milamberspace milamberspace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a full review of this PR — just a scoped, timely note on the dependency versions.

Apache HttpComponents Client just released 5.6.4: "Corrects application of SSL parameters in the async TLS upgrade method" (RELEASE_NOTES-5.6.x.txt). This PR pins httpclient5:5.5.1, and HTTPHC5Impl is exactly the kind of code that exercises that path — it uses the async H2 client with HttpVersionPolicy.NEGOTIATE for HTTP/2-over-TLS via ALPN, i.e. an async TLS upgrade. Worth pulling in the fix before this lands, rather than shipping the new HTTP/2 sampler with a known bug in SSL-parameter application during that exact upgrade.

See inline comment for the concrete version bump (and the matching httpcore5 pairing, since httpclient5:5.6.4 is built/tested against httpcore5:5.4.3, not 5.3.4).

This review was drafted by an AI-assisted tool and confirmed by an Apache JMeter maintainer.

@@ -107,6 +107,8 @@ dependencies {
because("User might still rely on commons-text")
}
api("org.apache.httpcomponents.client5:httpclient5:5.5.1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since HTTPHC5Impl (this PR) exercises HttpClient5's async TLS upgrade path for HTTP/2, worth bumping both of these before merge:

  • httpclient5: 5.5.15.6.4 — fixes "SSL parameter application in the async TLS upgrade strategy" (release notes)
  • httpcore5 / httpcore5-h2: 5.3.45.4.3 — the version httpclient5:5.6.4 is actually built and tested against (per its parent POM's httpcore.version property), so bumping only httpclient5 and leaving httpcore5 at 5.3.4 would be an incoherent pairing.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants