amphp/http-tunnel
AMPHP HTTP Tunnel provides asynchronous HTTP tunneling for PHP using Amp, enabling CONNECT-based proxy tunneling and transparent TCP-over-HTTP streams. Useful for building clients that need to reach services through HTTP proxies with non-blocking I/O.
Start by installing via Composer:
composer require amphp/http-tunnel
Begin with the HttpTunnel class, which accepts an Amp\Socket\Client and an optional proxy URL. The core pattern is establishing a tunneled connection to a target host/port using tunnel($host, $port), returning a non-blocking Amp\Socket\Socket-like stream. First use case: building an HTTPS client that must go through an authenticated HTTP proxy (e.g., corporate firewall), while preserving Amp’s async semantics. Example minimal snippet:
Amp\Loop::run(function () {
$client = new Amp\Http\Client\Network\Connector(
new Amp\Socket\Client(new Amp\Socket\Resolver)
);
$tunnel = new Amp\Http\Tunnel\HttpTunnel($client, 'http://proxy.example.com:8080');
$socket = $tunnel->tunnel('example.com', 443);
// Now use $socket like any Amp socket (e.g., wrap in TLS)
});
HttpTunnel, then pass the returned socket into TLS negotiators (Amp\Socket\TlsServerContext, Amp\Http\Client\TlsConnector), or custom protocol clients (e.g., gRPC, WebSocket).HttpTunnel instance for multiple concurrent targets—AMPH’s event loop handles concurrency; the tunnel only sets up the initial CONNECT request per stream.http://user:pass@proxy.local:3128) or configure headers via the underlying Connector’s request modifier hooks (if extending Connector).Amp\Http\Tunnel\TunnelException on failures and fallback to direct connection if needed.Amp\Socket\Client timeouts globally or wrap calls in Amp\Promise\timeout().http://), even if port 80—omit http:// and you’ll get cryptic parsing errors.HttpTunnel does not buffer response bodies (it expects only 2xx/3xx codes); if your proxy returns HTML on auth failure, the socket may hang until timeout. Check proxy health first.amphp/http-client’s built-in proxy support instead.Amp\Socket\ServerContext::$debug = true and inspect request logs—CONNECT requests are visible but may be masked by proxy logs.Proxy-Authorization), extend HttpTunnel and override createConnectRequest().How can I help you explore Laravel packages today?