1+ // Package client exposes Fiber's HTTP client built on top of fasthttp.
2+ //
3+ // It allows constructing new clients or wrapping existing fasthttp transports
4+ // so applications can share pools, dialers, and TLS settings between Fiber and
5+ // lower-level fasthttp integrations.
16package client
27
38import (
@@ -24,14 +29,14 @@ import (
2429
2530var ErrFailedToAppendCert = errors .New ("failed to append certificate" )
2631
27- // Client is used to create a Fiber client with client-level settings that
28- // apply to all requests made by the client .
32+ // Client provides Fiber's high-level HTTP API while delegating transport work
33+ // to fasthttp.Client, fasthttp.HostClient, or fasthttp.LBClient implementations .
2934//
30- // The Fiber client also provides an option to override or merge most of the
31- // client settings at the request level .
35+ // Settings configured on the client are shared across every request and may be
36+ // overridden per request when needed .
3237type Client struct {
33- logger log.CommonLogger
34- fasthttp * fasthttp. Client
38+ logger log.CommonLogger
39+ transport httpClientTransport
3540
3641 header * Header
3742 params * QueryParam
@@ -61,6 +66,72 @@ type Client struct {
6166 disablePathNormalizing bool
6267}
6368
69+ // Do executes the request using the underlying fasthttp transport.
70+ //
71+ // It mirrors [fasthttp.Client.Do], [fasthttp.HostClient.Do], or
72+ // [fasthttp.LBClient.Do] depending on how the Fiber client was constructed.
73+ func (c * Client ) Do (req * fasthttp.Request , resp * fasthttp.Response ) error {
74+ return c .transport .Do (req , resp )
75+ }
76+
77+ // DoTimeout executes the request and waits for a response up to the provided timeout.
78+ // It mirrors the behavior of the respective fasthttp client's DoTimeout implementation.
79+ func (c * Client ) DoTimeout (req * fasthttp.Request , resp * fasthttp.Response , timeout time.Duration ) error {
80+ return c .transport .DoTimeout (req , resp , timeout )
81+ }
82+
83+ // DoDeadline executes the request and waits for a response until the provided deadline.
84+ // It mirrors the behavior of the respective fasthttp client's DoDeadline implementation.
85+ func (c * Client ) DoDeadline (req * fasthttp.Request , resp * fasthttp.Response , deadline time.Time ) error {
86+ return c .transport .DoDeadline (req , resp , deadline )
87+ }
88+
89+ // DoRedirects executes the request following redirects up to maxRedirects.
90+ func (c * Client ) DoRedirects (req * fasthttp.Request , resp * fasthttp.Response , maxRedirects int ) error {
91+ return c .transport .DoRedirects (req , resp , maxRedirects )
92+ }
93+
94+ // CloseIdleConnections closes idle connections on the underlying fasthttp transport when supported.
95+ func (c * Client ) CloseIdleConnections () {
96+ c .transport .CloseIdleConnections ()
97+ }
98+
99+ func (c * Client ) currentTLSConfig () * tls.Config {
100+ return c .transport .TLSConfig ()
101+ }
102+
103+ func (c * Client ) applyTLSConfig (config * tls.Config ) {
104+ c .transport .SetTLSConfig (config )
105+ }
106+
107+ func (c * Client ) applyDial (dial fasthttp.DialFunc ) {
108+ c .transport .SetDial (dial )
109+ }
110+
111+ // FasthttpClient returns the underlying *fasthttp.Client if the client was created with one.
112+ func (c * Client ) FasthttpClient () * fasthttp.Client {
113+ if client , ok := c .transport .(* standardClientTransport ); ok {
114+ return client .client
115+ }
116+ return nil
117+ }
118+
119+ // HostClient returns the underlying fasthttp.HostClient if the client was created with one.
120+ func (c * Client ) HostClient () * fasthttp.HostClient {
121+ if client , ok := c .transport .(* hostClientTransport ); ok {
122+ return client .client
123+ }
124+ return nil
125+ }
126+
127+ // LBClient returns the underlying fasthttp.LBClient if the client was created with one.
128+ func (c * Client ) LBClient () * fasthttp.LBClient {
129+ if client , ok := c .transport .(* lbClientTransport ); ok {
130+ return client .client
131+ }
132+ return nil
133+ }
134+
64135// R creates a new Request associated with the client.
65136func (c * Client ) R () * Request {
66137 return AcquireRequest ().SetClient (c )
@@ -163,18 +234,23 @@ func (c *Client) SetCBORUnmarshal(f utils.CBORUnmarshal) *Client {
163234// TLSConfig returns the client's TLS configuration.
164235// If none is set, it initializes a new one.
165236func (c * Client ) TLSConfig () * tls.Config {
166- if c .fasthttp .TLSConfig == nil {
167- c .fasthttp .TLSConfig = & tls.Config {
168- MinVersion : tls .VersionTLS12 ,
169- }
170- }
237+ c .mu .Lock ()
238+ defer c .mu .Unlock ()
171239
172- return c .fasthttp .TLSConfig
240+ if cfg := c .currentTLSConfig (); cfg != nil {
241+ return cfg
242+ }
243+ cfg := & tls.Config {MinVersion : tls .VersionTLS12 }
244+ c .applyTLSConfig (cfg )
245+ return cfg
173246}
174247
175248// SetTLSConfig sets the TLS configuration for the client.
176249func (c * Client ) SetTLSConfig (config * tls.Config ) * Client {
177- c .fasthttp .TLSConfig = config
250+ c .mu .Lock ()
251+ defer c .mu .Unlock ()
252+
253+ c .applyTLSConfig (config )
178254 return c
179255}
180256
@@ -232,7 +308,10 @@ func (c *Client) SetRootCertificateFromString(pem string) *Client {
232308
233309// SetProxyURL sets the proxy URL for the client. This affects all subsequent requests.
234310func (c * Client ) SetProxyURL (proxyURL string ) error {
235- c .fasthttp .Dial = fasthttpproxy .FasthttpHTTPDialer (proxyURL )
311+ c .mu .Lock ()
312+ defer c .mu .Unlock ()
313+
314+ c .applyDial (fasthttpproxy .FasthttpHTTPDialer (proxyURL ))
236315 return nil
237316}
238317
@@ -514,7 +593,7 @@ func (c *Client) SetDial(dial fasthttp.DialFunc) *Client {
514593 c .mu .Lock ()
515594 defer c .mu .Unlock ()
516595
517- c .fasthttp . Dial = dial
596+ c .applyDial ( dial )
518597 return c
519598}
520599
@@ -532,9 +611,11 @@ func (c *Client) Logger() log.CommonLogger {
532611 return c .logger
533612}
534613
535- // Reset resets the client to its default state, clearing most configurations.
614+ // Reset resets the client to its default state, clearing most configurations
615+ // and replacing the underlying transport with a new fasthttp.Client so future
616+ // requests resume with Fiber's standard transport settings.
536617func (c * Client ) Reset () {
537- c .fasthttp = & fasthttp.Client {}
618+ c .transport = newStandardClientTransport ( & fasthttp.Client {})
538619 c .baseURL = ""
539620 c .timeout = 0
540621 c .userAgent = ""
@@ -659,8 +740,28 @@ func NewWithClient(c *fasthttp.Client) *Client {
659740 if c == nil {
660741 panic ("fasthttp.Client must not be nil" )
661742 }
743+ return newClient (newStandardClientTransport (c ))
744+ }
745+
746+ // NewWithHostClient creates and returns a new Client object from an existing fasthttp.HostClient.
747+ func NewWithHostClient (c * fasthttp.HostClient ) * Client {
748+ if c == nil {
749+ panic ("fasthttp.HostClient must not be nil" )
750+ }
751+ return newClient (newHostClientTransport (c ))
752+ }
753+
754+ // NewWithLBClient creates and returns a new Client object from an existing fasthttp.LBClient.
755+ func NewWithLBClient (c * fasthttp.LBClient ) * Client {
756+ if c == nil {
757+ panic ("fasthttp.LBClient must not be nil" )
758+ }
759+ return newClient (newLBClientTransport (c ))
760+ }
761+
762+ func newClient (transport httpClientTransport ) * Client {
662763 return & Client {
663- fasthttp : c ,
764+ transport : transport ,
664765 header : & Header {
665766 RequestHeader : & fasthttp.RequestHeader {},
666767 },
0 commit comments