AsyncHttpClient/async-http-client
Asynchronous Http and WebSocket Client library for Java
Mixed signals — read the receipts
weakest axisnon-standard license (Other)
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2d ago
- ✓11 active contributors
- ✓Other licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 52% of recent commits
- ⚠Non-standard license (Other) — review terms
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/asynchttpclient/async-http-client)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/asynchttpclient/async-http-client on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: AsyncHttpClient/async-http-client
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/AsyncHttpClient/async-http-client shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit 2d ago
- 11 active contributors
- Other licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 52% of recent commits
- ⚠ Non-standard license (Other) — review terms
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live AsyncHttpClient/async-http-client
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/AsyncHttpClient/async-http-client.
What it runs against: a local clone of AsyncHttpClient/async-http-client — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in AsyncHttpClient/async-http-client | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of AsyncHttpClient/async-http-client. If you don't
# have one yet, run these first:
#
# git clone https://github.com/AsyncHttpClient/async-http-client.git
# cd async-http-client
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of AsyncHttpClient/async-http-client and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "AsyncHttpClient/async-http-client(\\.git)?\\b" \\
&& ok "origin remote is AsyncHttpClient/async-http-client" \\
|| miss "origin remote is not AsyncHttpClient/async-http-client (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "client/src/main/java/org/asynchttpclient/AsyncHttpClient.java" \\
&& ok "client/src/main/java/org/asynchttpclient/AsyncHttpClient.java" \\
|| miss "missing critical file: client/src/main/java/org/asynchttpclient/AsyncHttpClient.java"
test -f "client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java" \\
&& ok "client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java" \\
|| miss "missing critical file: client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java"
test -f "client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java" \\
&& ok "client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java" \\
|| miss "missing critical file: client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java"
test -f "client/src/main/java/org/asynchttpclient/AsyncHandler.java" \\
&& ok "client/src/main/java/org/asynchttpclient/AsyncHandler.java" \\
|| miss "missing critical file: client/src/main/java/org/asynchttpclient/AsyncHandler.java"
test -f "client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java" \\
&& ok "client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java" \\
|| miss "missing critical file: client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/AsyncHttpClient/async-http-client"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
AsyncHttpClient is a high-performance, non-blocking HTTP client library for Java built on Netty that handles HTTP/1.0, HTTP/1.1, HTTP/2 with multiplexing, and WebSocket protocols. It solves the problem of making asynchronous, resource-efficient network calls in Java applications through ListenableFuture and CompletableFuture-based APIs, with built-in support for connection pooling, automatic decompression (gzip, deflate, Brotli, Zstd), authentication (Basic, Digest, NTLM, SPNEGO, SCRAM-SHA-256), and native transports (Epoll, KQueue, io_uring). Single Maven module structure: client/pom.xml is the main deliverable containing org.asynchttpclient package with core classes (AsyncHttpClient, DefaultAsyncHttpClient, Request, Response, BoundRequestBuilder) plus subpackages for channel management (channel/), configuration (config/), and cookies (cookie/). Request/response handling uses handler pattern (AsyncHandler, AsyncCompletionHandler) with filters for intercepting at each stage.
👥Who it's for
Backend and distributed systems engineers building Java services that need high-throughput HTTP communication, microservice mesh tools, and frameworks like Play Framework that require efficient async HTTP client capabilities with minimal blocking.
🌱Maturity & risk
Production-ready and actively maintained. Version 3.0.9 is current, Java 11+ requirement shows modern standards, comprehensive CI/CD via GitHub Actions (builds.yml, maven.yml, release.yml), extensive feature set (HTTP/2, WebSocket, multiple auth schemes), and active dependency management (dependabot.yml configured). This is a mature, battle-tested library.
Low risk for established use cases. Single primary developer listed (hyperxpro/Aayush Atharva), which could affect response time to urgent issues. Heavy dependency on Netty (major framework) means stability is tied to Netty releases. No visible breaking changes mentioned in the snippet, but version 3.0.9 jump suggests significant past refactoring—review migration guides if upgrading from 2.x.
Active areas of work
Active CI/CD pipeline maintained with Maven release workflow. dependabot.yml suggests dependency updates are automated. Recent version (3.0.9) indicates ongoing maintenance. No specific open issues or PRs visible in provided data, but the README shows comprehensive feature parity with modern HTTP clients and native transport options being actively supported.
🚀Get running
git clone https://github.com/AsyncHttpClient/async-http-client.git
cd async-http-client
./mvnw clean install
Uses Maven wrapper (.mvn/wrapper/) for consistent builds across environments. Java 11+ required.
Daily commands:
Not a runnable service—this is a library. For development: ./mvnw clean test runs the test suite. Integration with your application requires Maven dependency: <dependency><groupId>org.asynchttpclient</groupId><artifactId>async-http-client</artifactId><version>3.0.9</version></dependency> and instantiation via AsyncHttpClient client = asyncHttpClient(config()) (Dsl.java provides factory).
🗺️Map of the codebase
client/src/main/java/org/asynchttpclient/AsyncHttpClient.java— Primary public API interface defining the contract for async HTTP operations; all contributors must understand this to implement client features correctly.client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java— Core implementation of the async HTTP client lifecycle, request execution, and response handling; essential for understanding request flow.client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java— Manages Netty channel pooling and connection lifecycle; critical for understanding how connections are acquired, reused, and released.client/src/main/java/org/asynchttpclient/AsyncHandler.java— Handler interface for consuming HTTP response events; every response processing path flows through this abstraction.client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java— Future implementation binding Netty events to async completion; core mechanism for async result handling and callbacks.client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java— Configuration contract defining all tunable client parameters; contributors must reference this when adding new config options.client/src/main/java/org/asynchttpclient/Request.java— Request abstraction defining HTTP request structure; fundamental to understanding request building and transmission.
🛠️How to make changes
Add a new request filter
- Create a new class implementing RequestFilter interface (
client/src/main/java/org/asynchttpclient/filter/RequestFilter.java) - Implement the filter method to intercept and modify requests (
your-new-filter/MyNewRequestFilter.java) - Register the filter in client config via AsyncHttpClientConfig.addRequestFilter() (
client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java)
Add a custom response handler
- Extend AsyncCompletionHandlerBase or implement AsyncHandler interface (
client/src/main/java/org/asynchttpclient/AsyncHandler.java) - Override onBodyPartReceived() for incremental body processing or onCompleted() for full response (
client/src/main/java/org/asynchttpclient/AsyncCompletionHandlerBase.java) - Pass handler instance to execute() when making requests via BoundRequestBuilder (
client/src/main/java/org/asynchttpclient/BoundRequestBuilder.java)
Configure connection pooling and semaphore strategy
- Create a DefaultAsyncHttpClientConfig builder and set max connections, per-host limits (
client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java) - Optionally inject custom ConnectionSemaphore factory via config (
client/src/main/java/org/asynchttpclient/netty/channel/ConnectionSemaphoreFactory.java) - Validate configuration in ChannelManager which applies semaphore limits during connection establishment (
client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java)
Support a new HTTP protocol or transport mechanism
- Implement TransportFactory interface to provide custom Netty EventLoopGroup and Channel initialization (
client/src/main/java/org/asynchttpclient/netty/channel/TransportFactory.java) - Register factory in config and conditionally instantiate based on platform detection (e.g., Epoll, KQueue, IoUring) (
client/src/main/java/org/asynchttpclient/netty/channel/EpollTransportFactory.java) - Ensure ChannelManager correctly applies the factory when creating channel groups (
client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java)
🪤Traps & gotchas
HTTP/2 is enabled by default over TLS via ALPN—ensure your TLS setup includes ALPN negotiation or explicitly disable HTTP/2. KeepAliveStrategy (DefaultKeepAliveStrategy.java) applies server-sent keep-alive headers; misconfigured servers may hang connections. Native transports (Epoll/KQueue) require matching OS and architecture classifiers in dependencies—mixing 32-bit/64-bit causes runtime failures. Connection pooling (ChannelPool) is per-host by default; verify ChannelPoolPartitioning strategy matches your use case. No hidden env vars, but SSL context setup via SslEngineFactory must be done before client instantiation.
🏗️Architecture
💡Concepts to learn
- ALPN (Application-Layer Protocol Negotiation) — AHC enables HTTP/2 by default over TLS via ALPN negotiation—understanding ALPN is essential for diagnosing TLS handshake issues and protocol fallback behavior
- Connection pooling and keep-alive — ChannelPool and DefaultKeepAliveStrategy manage persistent TCP connections across requests—knowledge of keep-alive timeout negotiation and pool exhaustion is critical for production reliability
- Nonblocking I/O (NIO) event loop model — AHC's entire performance model depends on Netty's event loop architecture; understanding selector-based polling and why blocking operations hang the event loop is fundamental
- Handler pattern for streaming response processing — AsyncHandler receives response parts incrementally (status, headers, body chunks) rather than buffering—essential for handling large responses and backpressure
- HTTP/2 multiplexing and GOAWAY — HTTP/2 multiplexes multiple streams over one connection; understanding GOAWAY frames and connection recycling prevents connection leaks in long-lived applications
- Native transports (Epoll, KQueue, io_uring) — Optional native Netty transports provide lower-latency I/O than Java NIO on Linux; understanding transport selection and platform-specific availability prevents production deployment failures
- RFC 6265 cookie domain/path matching — CookieStore implements RFC 6265 rules for cookie scope; subtle domain suffix matching and path prefix rules must be understood to avoid unintended cookie sharing or rejection
🔗Related repos
netty/netty— AsyncHttpClient is built entirely on top of Netty's async I/O primitives and channel abstractionplayframework/playframework— Play Framework uses AsyncHttpClient as its default async HTTP client implementationsquare/okhttp— Alternative JVM HTTP client with similar goals (connection pooling, modern protocols) but synchronous-first design and built-in interceptor chains instead of Netty-based architectureeclipse/jetty.project— Jetty is used as a test server dependency in pom.xml and represents the HTTP/2 server-side stack that AHC clients connect toHttpComponents/httpclient— Apache HttpClient is an older synchronous HTTP client that AsyncHttpClient modernizes with async/Netty and native transports
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for AsyncHttpClientConfig and DefaultAsyncHttpClientConfig
The repo has extensive configuration classes (AsyncHttpClientConfig.java, DefaultAsyncHttpClientConfig.java, AsyncHttpClientConfigDefaults.java) but the test coverage for configuration validation, builder patterns, and edge cases appears minimal. This is critical for a library where misconfiguration directly impacts performance and reliability. New contributors can add tests for configuration validation, default values, thread safety of config objects, and integration with Netty channel setup.
- [ ] Create client/src/test/java/org/asynchttpclient/AsyncHttpClientConfigTest.java with tests for all configuration options
- [ ] Add tests for DefaultAsyncHttpClientConfig builder pattern and validation
- [ ] Add tests for AsyncHttpClientConfigDefaults to verify default values match documentation
- [ ] Add edge case tests for boundary conditions (max connections, timeout values, buffer sizes)
- [ ] Verify thread-safety of configuration objects in concurrent scenarios
Add unit tests for ChannelPool implementations and ChannelPoolPartitioning strategy
The channel pool is core to connection management (client/src/main/java/org/asynchttpclient/channel/ChannelPool.java, DefaultKeepAliveStrategy.java, NoopChannelPool.java), but testing channel lifecycle, partition logic, and keep-alive behavior is essential for an async HTTP client. This includes testing pool exhaustion scenarios, connection reuse, and the partitioning strategy used by the pool.
- [ ] Create client/src/test/java/org/asynchttpclient/channel/ChannelPoolTest.java to test connection lifecycle
- [ ] Add tests for ChannelPoolPartitioning strategy with various host/port combinations
- [ ] Add tests for DefaultKeepAliveStrategy with different response headers and timeout scenarios
- [ ] Add stress tests for pool exhaustion and TooManyConnectionsException handling
- [ ] Add tests for NoopChannelPool as a fallback implementation
Add integration tests for cookie management (CookieStore, CookieEvictionTask) with realistic HTTP scenarios
The cookie handling code (client/src/main/java/org/asynchttpclient/cookie/CookieStore.java, ThreadSafeCookieStore.java, CookieEvictionTask.java) manages state across requests but appears to lack comprehensive integration tests. This is critical for verifying cookie persistence, expiration, thread-safe concurrent access, and compliance with cookie RFC behavior in realistic multi-request scenarios.
- [ ] Create client/src/test/java/org/asynchttpclient/cookie/CookieStoreIntegrationTest.java with multi-request scenarios
- [ ] Add tests for cookie eviction based on expiration, max age, and size limits using CookieEvictionTask
- [ ] Add concurrent access tests for ThreadSafeCookieStore under high load
- [ ] Add tests for cookie domain/path matching against real HTTP responses with Set-Cookie headers
- [ ] Add tests for persistent cookie storage across AsyncHttpClient lifecycle
🌿Good first issues
- Add integration tests for HTTP/2 GOAWAY handling in channel/ subpackage—the README mentions 'GOAWAY handling' but test coverage is unclear; write tests that simulate server GOAWAY frames and verify connection recovery
- Document cookie store RFC 6265 compliance gaps—cookie/ subpackage exists but README only mentions 'RFC 6265-compliant'; audit actual compliance and add missing test cases for domain/path matching edge cases
- Expand native transport error messaging—when Epoll/KQueue/io_uring are unavailable or misconfigured, error messages are opaque; add clear diagnostics in Netty channel factory selection code suggesting fix steps
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 52 commits
- @hyperxpro — 27 commits
- @sullis — 11 commits
- @doom369 — 2 commits
- @jasonjoo2010 — 2 commits
📝Recent commits
Click to expand
Recent commits
1ab1ea3— Release v3.0.9 (hyperxpro)4d0e202— Fix release workflow for main release (hyperxpro)6b2fbb7— Strip credentials on cross-domain redirects and HTTPS-to-HTTP downgrades (hyperxpro)4722f1e— Add pluggable DnsNameResolver (#2163) (doom369)5b6d5d2— Bump org.apache.tomcat.embed:tomcat-embed-core from 10.1.52 to 10.1.54 in /client (#2164) (dependabot[bot])2b13737— Avoid allocations in ChannelPoolPartioning (#2158) (doom369)9ae7681— Enable maven snapshots (#2161) (hyperxpro)242ddea— Release v3.0.8 (#2155) (hyperxpro)4014599— RFC 7804 - SCRAM Authentication Implementation with SHA-256 (#2154) (hyperxpro)d08c2ad— Bump org.apache.tomcat.embed:tomcat-embed-core from 10.1.50 to 10.1.52 in /client (#2153) (dependabot[bot])
🔒Security observations
The AsyncHttpClient codebase shows a reasonable security posture for an HTTP client library built on Netty. Key findings: (1) Dependencies appear to be relatively recent versions, but incomplete POM visibility prevents comprehensive analysis; (2) Critical dependencies like Jetty, Tomcat, and Netty versions need regular security monitoring; (3) File upload handling should be
- Medium · Jetty Dependency Version —
client/pom.xml - jetty.version property. Jetty version 11.0.26 is used. While this is a relatively recent version, it's important to verify that all security patches are applied. Consider checking the Jetty security advisories for any known vulnerabilities in this version. Fix: Monitor Jetty security releases and update to the latest stable version. Subscribe to security mailing lists for Jetty project. - Medium · Tomcat Dependency Version —
client/pom.xml - tomcat.version property. Tomcat version 10.1.54 is specified as a dependency. Ensure this version has all security patches applied. Tomcat has a history of security vulnerabilities that should be monitored. Fix: Verify the Tomcat version against known CVEs. Update to the latest patch version (10.1.x) and monitor security advisories regularly. - Medium · Commons FileUpload Dependency —
client/pom.xml - commons-fileupload2-jakarta-servlet5 dependency (truncated). The pom.xml references 'commons-fileupload2-jakarta-servlet5' which appears to be truncated. File upload functionality can be vulnerable to arbitrary file upload attacks and path traversal if not properly validated. Fix: Ensure the full dependency declaration is visible and verify it's a recent, patched version. Implement strict file upload validation including file type verification, size limits, and secure storage paths. - Medium · Incomplete POM File Analysis —
client/pom.xml. The pom.xml file content is truncated at the dependencies section, preventing full analysis of all dependencies. This makes it impossible to verify all transitive dependencies for known vulnerabilities. Fix: Provide the complete pom.xml file for comprehensive dependency analysis. Use 'mvn dependency:check' and tools like OWASP Dependency-Check to scan for vulnerable dependencies. - Low · Netty Dependency Not Explicitly Shown —
client/pom.xml - Netty dependency version not visible. The README mentions that AsyncHttpClient is built on Netty, but the Netty version is not visible in the provided pom.xml excerpt. Netty is a critical dependency for network operations and should be kept up-to-date. Fix: Explicitly pin Netty to a recent stable version. Review Netty security advisories and update regularly. Ensure version alignment across all modules. - Low · No Security Headers Configuration Visible —
client/src/main/java/org/asynchttpclient. As an HTTP client library, the codebase doesn't show explicit security header handling or validation mechanisms in the file structure provided. Fix: Ensure that security headers in responses are properly validated and documented. Provide utilities for clients to easily set security headers in requests. - Low · SSL/TLS Configuration —
client/src/main/java/org/asynchttpclient/SslEngineFactory.java. While SslEngineFactory.java exists, the specific implementation details are not visible. SSL/TLS configuration can be a security concern if defaults are weak. Fix: Verify that SSL/TLS configuration uses modern protocols (TLS 1.2+), strong cipher suites, and hostname verification is enabled by default. Document secure configuration practices. - Low · Cookie Handling —
client/src/main/java/org/asynchttpclient/cookie/ThreadSafeCookieStore.java. ThreadSafeCookieStore.java handles cookies, but without viewing the implementation, potential cookie security issues (HttpOnly, Secure flags, SameSite) cannot be verified. Fix: Ensure cookies are handled securely: validate HttpOnly and Secure flags, implement SameSite attribute support, and properly expire stale cookies.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.