Skip to content

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

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

Add HttpClient5 sampler implementation with HTTP/2 support#6742
andreaslind01 wants to merge 19 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
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.

1 participant