@@ -11,6 +11,9 @@ import (
1111// defaultRedirectLimit mirrors fasthttp's default when callers supply a negative redirect cap.
1212const defaultRedirectLimit = 16
1313
14+ // httpClientTransport unifies the operations exposed by the Fiber client across
15+ // the fasthttp.Client, fasthttp.HostClient, and fasthttp.LBClient adapters so
16+ // helper logic can treat the concrete transports uniformly.
1417type httpClientTransport interface {
1518 Do (req * fasthttp.Request , resp * fasthttp.Response ) error
1619 DoTimeout (req * fasthttp.Request , resp * fasthttp.Response , timeout time.Duration ) error
@@ -153,9 +156,9 @@ func (l *lbClientTransport) DoDeadline(req *fasthttp.Request, resp *fasthttp.Res
153156 return l .client .DoDeadline (req , resp , deadline )
154157}
155158
156- // DoRedirects proxies redirect handling through doRedirectsWithClient so
157- // lbClientTransport matches fasthttp.Client semantics even though
158- // fasthttp.LBClient does not publish a dedicated DoRedirects helper .
159+ // DoRedirects proxies redirect handling through doRedirectsWithClient so the
160+ // load-balanced transport mirrors fasthttp.Client semantics despite
161+ // fasthttp.LBClient not exposing DoRedirects directly .
159162func (l * lbClientTransport ) DoRedirects (req * fasthttp.Request , resp * fasthttp.Response , maxRedirects int ) error {
160163 return doRedirectsWithClient (req , resp , maxRedirects , l .client )
161164}
@@ -195,15 +198,15 @@ func (l *lbClientTransport) Client() any {
195198}
196199
197200// forEachHostClient applies fn to every host client reachable from the provided
198- // load balancer, recursing into nested balancing clients .
201+ // load balancer by recursively following nested balancers and wrapper types .
199202func forEachHostClient (lb * fasthttp.LBClient , fn func (* fasthttp.HostClient )) {
200203 for _ , c := range lb .Clients {
201204 walkBalancingClient (c , fn )
202205 }
203206}
204207
205- // walkBalancingClient traverses nested balancing clients and invokes fn for
206- // each host client encountered .
208+ // walkBalancingClient traverses balancing clients recursively, invoking fn for
209+ // every host client discovered beneath the current node .
207210func walkBalancingClient (client any , fn func (* fasthttp.HostClient )) {
208211 switch c := client .(type ) {
209212 case * fasthttp.HostClient :
@@ -220,8 +223,8 @@ func walkBalancingClient(client any, fn func(*fasthttp.HostClient)) {
220223}
221224
222225// extractTLSConfig returns the first TLS configuration discovered while walking
223- // the provided balancing clients, enabling cached reuse across nested load
224- // balancers.
226+ // the provided balancing clients so cached settings flow through nested load
227+ // balancers without redundant traversal .
225228func extractTLSConfig (clients []fasthttp.BalancingClient ) * tls.Config {
226229 var cfg * tls.Config
227230 for _ , c := range clients {
@@ -239,8 +242,7 @@ func extractTLSConfig(clients []fasthttp.BalancingClient) *tls.Config {
239242}
240243
241244// extractDial returns the first dial function discovered while walking the
242- // provided balancing clients, ensuring overrides propagate through nested
243- // transports.
245+ // provided balancing clients so overrides propagate through nested transports.
244246func extractDial (clients []fasthttp.BalancingClient ) fasthttp.DialFunc {
245247 var dial fasthttp.DialFunc
246248 for _ , c := range clients {
@@ -257,9 +259,9 @@ func extractDial(clients []fasthttp.BalancingClient) fasthttp.DialFunc {
257259 return dial
258260}
259261
260- // walkBalancingClientWithBreak traverses balancing clients and invokes fn for
261- // each host client encountered until fn returns true, allowing callers to stop
262- // the traversal early when a match is found.
262+ // walkBalancingClientWithBreak traverses balancing clients recursively and
263+ // invokes fn for each host client until fn signals success, enabling early
264+ // termination once a match is found.
263265func walkBalancingClientWithBreak (client any , fn func (* fasthttp.HostClient ) bool ) bool {
264266 switch c := client .(type ) {
265267 case * fasthttp.HostClient :
@@ -280,8 +282,9 @@ func walkBalancingClientWithBreak(client any, fn func(*fasthttp.HostClient) bool
280282 return false
281283}
282284
283- // redirectClient describes the minimal surface needed by doRedirectsWithClient to
284- // issue HTTP requests while preserving fasthttp redirect semantics.
285+ // redirectClient describes the minimal Do-capable surface needed by
286+ // doRedirectsWithClient so transports that do not expose DoRedirects (such as
287+ // fasthttp.LBClient) can participate in redirect handling.
285288type redirectClient interface {
286289 Do (req * fasthttp.Request , resp * fasthttp.Response ) error
287290}
@@ -345,8 +348,10 @@ func doRedirectsWithClient(req *fasthttp.Request, resp *fasthttp.Response, maxRe
345348// restricting schemes to HTTP/S so caller-provided Location headers cannot
346349// trigger arbitrary transports.
347350func composeRedirectURL (base string , location []byte , disablePathNormalizing bool ) (string , error ) {
348- if bytes .ContainsAny (location , "\r \n " ) {
349- return "" , fasthttp .ErrorInvalidURI
351+ for _ , b := range location {
352+ if b < 0x20 || b == 0x7f {
353+ return "" , fasthttp .ErrorInvalidURI
354+ }
350355 }
351356
352357 uri := fasthttp .AcquireURI ()
0 commit comments