<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Documentation on poseidon-http-client</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/</link><description>Recent content in Documentation on poseidon-http-client</description><generator>Hugo</generator><language>en</language><atom:link href="https://lodgvideon.github.io/poseidon-http-client/en/docs/index.xml" rel="self" type="application/rss+xml"/><item><title>Getting started</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/getting-started/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://lodgvideon.github.io/poseidon-http-client/en/docs/getting-started/</guid><description>&lt;h1 id="getting-started"&gt;Getting started&lt;a class="anchor" href="#getting-started"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;poseidon-http-client is a low-level HTTP client for Go. It implements HTTP/1.1, HTTP/2, and HTTP/3 from scratch — its own framing, HPACK, QPACK, and QUIC stack — with no &lt;code&gt;net/http&lt;/code&gt; and no third-party protocol libraries. It is built for load generators and tools that need direct control over connections, streams, and flow control.&lt;/p&gt;
&lt;h2 id="install"&gt;Install&lt;a class="anchor" href="#install"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Requires Go 1.25 or newer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go get github.com/lodgvideon/poseidon-http-client&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="the-request-model"&gt;The request model&lt;a class="anchor" href="#the-request-model"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All three protocol versions share the same API. You build a client with a constructor, then call &lt;code&gt;Do&lt;/code&gt; with a context, a request, and a caller-owned &lt;code&gt;*client.Response&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>HTTP/1.1</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/http1/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://lodgvideon.github.io/poseidon-http-client/en/docs/http1/</guid><description>&lt;h1 id="http11"&gt;HTTP/1.1&lt;a class="anchor" href="#http11"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Use HTTP/1.1 when the target server does not speak HTTP/2, or when you
want to test its HTTP/1.1 path specifically and must prevent the ALPN
negotiation from upgrading the connection to h2.&lt;/p&gt;
&lt;p&gt;HTTP/1.1 has the same constructor set as HTTP/2 and HTTP/3:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Constructor&lt;/th&gt;
					&lt;th&gt;Transport&lt;/th&gt;
					&lt;th&gt;Shape&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;NewH1Client(addr, dialer, opts...)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;TransportH1SingleConn&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;One connection, auto-redial. Requests are serialized.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;NewH1PoolClient(addr, dialer, pool, opts...)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;TransportH1Pool&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Up to &lt;code&gt;MaxConnsPerHost&lt;/code&gt; connections. That number is the request concurrency.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;NewManagedH1Client(resolver, dialer, opts...)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;TransportH1Managed&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Resolver + Selector service discovery; a per-address HTTP/1.1 sub-pool fans out.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="forcing-http11"&gt;Forcing HTTP/1.1&lt;a class="anchor" href="#forcing-http11"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Two things pin the protocol:&lt;/p&gt;</description></item><item><title>HTTP/2</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/http2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://lodgvideon.github.io/poseidon-http-client/en/docs/http2/</guid><description>&lt;h1 id="http2"&gt;HTTP/2&lt;a class="anchor" href="#http2"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The HTTP/2 client implements RFC 7540 and HPACK (RFC 7541) from scratch — no &lt;code&gt;net/http&lt;/code&gt;, no &lt;code&gt;golang.org/x/net/http2&lt;/code&gt;. Three constructors cover the common topologies: one connection, a per-host pool, or a resolver-driven set of backends. All three return a &lt;code&gt;*client.Client&lt;/code&gt; with the same &lt;code&gt;Do&lt;/code&gt; / &lt;code&gt;DoStream&lt;/code&gt; API.&lt;/p&gt;
&lt;h2 id="single-connection"&gt;Single connection&lt;a class="anchor" href="#single-connection"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;client.NewSingleConnClient&lt;/code&gt; holds one connection and redials automatically when it drops. This is &lt;code&gt;examples/http2/main.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Command http2-example issues a single HTTP/2 GET with the poseidon client.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// TransportSingleConn (the default) negotiates h2 over TLS and reuses one&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// connection with automatic redial.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//	go run ./examples/http2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;crypto/tls&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/lodgvideon/poseidon-http-client/client&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/lodgvideon/poseidon-http-client/conn&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewSingleConnClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;		&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;www.cloudflare.com:443&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;		&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TLSDialer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;			&lt;/span&gt;&lt;span class="nx"&gt;ServerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;www.cloudflare.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;			&lt;/span&gt;&lt;span class="nx"&gt;NextProtos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;		&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;		&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;build client: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="c1"&gt;// Response is caller-owned and reusable; Reset() clears it between requests.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;		&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;GET /: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;HTTP/2 %d — %d bytes\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Response&lt;/code&gt; is caller-owned: allocate it once, call &lt;code&gt;resp.Reset()&lt;/code&gt; between requests. &lt;code&gt;client.GET(path)&lt;/code&gt; is shorthand; build a &lt;code&gt;client.Request{Method, Scheme, Authority, Path, BodyMode}&lt;/code&gt; directly for full control.&lt;/p&gt;</description></item><item><title>HTTP/3</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/http3/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://lodgvideon.github.io/poseidon-http-client/en/docs/http3/</guid><description>&lt;h1 id="http3"&gt;HTTP/3&lt;a class="anchor" href="#http3"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The HTTP/3 client (RFC 9114) runs over a QUIC stack (RFC 9000/9001/9002) and QPACK codec (RFC 9204) implemented in this repository — no &lt;code&gt;quic-go&lt;/code&gt;, no cgo. Only the TLS 1.3 handshake itself comes from the standard library &lt;code&gt;crypto/tls&lt;/code&gt;; packet protection, loss recovery, congestion control, and flow control are poseidon code.&lt;/p&gt;
&lt;p&gt;The request API is the same &lt;code&gt;Do&lt;/code&gt; / &lt;code&gt;DoStream&lt;/code&gt; you use with HTTP/2. A &lt;code&gt;client.Request&lt;/code&gt; and &lt;code&gt;client.Response&lt;/code&gt; do not change between transports; switching a load test from H2 to H3 is a constructor change.&lt;/p&gt;</description></item><item><title>Features &amp; advantages</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/features/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://lodgvideon.github.io/poseidon-http-client/en/docs/features/</guid><description>&lt;h1 id="features--advantages"&gt;Features &amp;amp; advantages&lt;a class="anchor" href="#features--advantages"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="support-matrix"&gt;Support matrix&lt;a class="anchor" href="#support-matrix"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All three protocol versions share the same request API: &lt;code&gt;client.Do&lt;/code&gt; / &lt;code&gt;client.DoStream&lt;/code&gt; with a caller-owned, reusable &lt;code&gt;client.Response&lt;/code&gt;. Compression is shared too: responses are decoded for all of gzip, deflate, br, and zstd (the client advertises &lt;code&gt;accept-encoding: gzip, deflate, br, zstd&lt;/code&gt;), and &lt;code&gt;Request.CompressBody&lt;/code&gt; compresses request bodies — see &lt;a href="#compression"&gt;Compression&lt;/a&gt; below. What differs is how much of the protocol each transport exposes.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Protocol&lt;/th&gt;
					&lt;th&gt;Implementation&lt;/th&gt;
					&lt;th&gt;Constructors&lt;/th&gt;
					&lt;th&gt;Concurrent requests per connection&lt;/th&gt;
					&lt;th&gt;Pooling&lt;/th&gt;
					&lt;th&gt;Service discovery&lt;/th&gt;
					&lt;th&gt;Notable capabilities&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;HTTP/1.1&lt;/td&gt;
					&lt;td&gt;From scratch&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewH1Client&lt;/code&gt;, &lt;code&gt;NewH1PoolClient&lt;/code&gt;, &lt;code&gt;NewManagedH1Client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;No — one exchange per connection at a time (no pipelining)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewH1PoolClient&lt;/code&gt; (exclusive-checkout pool: &lt;code&gt;MaxConnsPerHost&lt;/code&gt; is the request concurrency)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewManagedH1Client&lt;/code&gt; (Resolver + Selector)&lt;/td&gt;
					&lt;td&gt;Keep-alive connection reuse; request bodies stream (&lt;code&gt;Request.BodyReader&lt;/code&gt;, chunked when length is unknown) but responses are always buffered into &lt;code&gt;Response.Body&lt;/code&gt; — &lt;code&gt;DoStream&lt;/code&gt; and &lt;code&gt;BodyStream&lt;/code&gt; return an error; ALPN fallback target: &lt;code&gt;TransportALPN&lt;/code&gt; selects HTTP/1.1 automatically when a server does not offer h2&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HTTP/2&lt;/td&gt;
					&lt;td&gt;RFC 7540 + HPACK (RFC 7541), from scratch&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewSingleConnClient&lt;/code&gt;, &lt;code&gt;NewPoolClient&lt;/code&gt;, &lt;code&gt;NewManagedClient&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Yes — stream multiplexing, gated by &lt;code&gt;MAX_CONCURRENT_STREAMS&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewPoolClient&lt;/code&gt; (per-host pool, least-loaded stream pick, idle eviction)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewManagedClient&lt;/code&gt; (Resolver + Selector)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;DoStream&lt;/code&gt; and request trailers; flow control; dynamic SETTINGS; GOAWAY drain; PING keepalive; server push (PUSH_PROMISE); request priority; extended CONNECT (RFC 8441, WebSockets over H2); CONTINUATION; HTTP CONNECT proxy dialers; h2c prior knowledge&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HTTP/3&lt;/td&gt;
					&lt;td&gt;RFC 9114 + QUIC (RFC 9000/9001/9002) + QPACK (RFC 9204), from scratch&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewH3Client&lt;/code&gt;, &lt;code&gt;NewH3PoolClient&lt;/code&gt;, &lt;code&gt;NewManagedH3Client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Yes — concurrent in-flight requests over one QUIC connection&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewH3PoolClient&lt;/code&gt; (multi-connection pool)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;NewManagedH3Client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;DoStream&lt;/code&gt;; dynamic QPACK in both directions (encode + decode); all TLS 1.3 AEADs (AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305); congestion control NewReno by default, opt-in BBR; on Linux: GSO batched send, GRO batched receive, bounded ACK coalescing&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;HTTP/1.1 has the same constructor set as the other two versions, but its pool is different in kind. HTTP/1.1 has no multiplexing: a single connection means strictly serial requests, so without a pool the client cannot generate HTTP/1.1 load at all. The pool hands out connections by exclusive checkout — one exchange per connection at a time — which makes &lt;code&gt;MaxConnsPerHost&lt;/code&gt; the request concurrency; &lt;code&gt;MaxStreamsPerConn&lt;/code&gt; does not apply. A request that finds every connection busy waits for one to free, bounded by the request context. Connections are kept alive and reused; a &lt;code&gt;Connection: close&lt;/code&gt;, a dead connection, or an exchange error discards the connection and redials. Pipelining is deliberately not implemented. The dialer must not offer the &lt;code&gt;h2&lt;/code&gt; ALPN token — use a plain TCP dialer, or a TLS dialer whose &lt;code&gt;NextProtos&lt;/code&gt; is only &lt;code&gt;&amp;quot;http/1.1&amp;quot;&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Disclaimer</title><link>https://lodgvideon.github.io/poseidon-http-client/en/docs/disclaimer/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://lodgvideon.github.io/poseidon-http-client/en/docs/disclaimer/</guid><description>&lt;h1 id="disclaimer"&gt;Disclaimer&lt;a class="anchor" href="#disclaimer"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;poseidon-http-client is young software. This is its first release. Read this page before depending on it.&lt;/p&gt;
&lt;h2 id="no-warranty"&gt;No warranty&lt;a class="anchor" href="#no-warranty"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The library is licensed under MIT and is provided &lt;strong&gt;as is&lt;/strong&gt;, without warranty of any kind. You use it at your own risk. See the &lt;a href="https://github.com/lodgvideon/poseidon-http-client/blob/main/LICENSE"&gt;LICENSE&lt;/a&gt; file for the exact terms.&lt;/p&gt;
&lt;h2 id="security-sensitive-code-no-third-party-audit"&gt;Security-sensitive code, no third-party audit&lt;a class="anchor" href="#security-sensitive-code-no-third-party-audit"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This library implements security-sensitive protocols from scratch: the QUIC transport (RFC 9000/9001/9002), TLS 1.3 record protection for QUIC, HPACK (RFC 7541), and QPACK (RFC 9204). It does not reuse &lt;code&gt;net/http&lt;/code&gt;, &lt;code&gt;quic-go&lt;/code&gt;, or any other established protocol implementation for these paths.&lt;/p&gt;</description></item></channel></rss>