Skip to content

🔥 feat: Add support for HostClient and LBClient#3774

Merged
ReneWerner87 merged 26 commits intomainfrom
refactor-client.client-for-fasthttp-compatibility
Oct 13, 2025
Merged

🔥 feat: Add support for HostClient and LBClient#3774
ReneWerner87 merged 26 commits intomainfrom
refactor-client.client-for-fasthttp-compatibility

Conversation

@gaby
Copy link
Member

@gaby gaby commented Oct 2, 2025

Summary

  • This pull request introduces support for fasthttp.HostClient and fasthttp.LBClient in the Fiber client, abstracting the transport layer to accommodate different fasthttp client types.

Fixes #3232

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds an internal transport abstraction for the Fiber HTTP client to wrap fasthttp.Client / fasthttp.HostClient / fasthttp.LBClient, routes request execution and TLS/dial/proxy configuration through the transport, exposes Do/DoTimeout/DoDeadline/DoRedirects/CloseIdleConnections on Client, updates core call sites to use the wrapper, expands tests, and updates docs and AGENTS.md checks.

Changes

Cohort / File(s) Summary
Guidelines updates
AGENTS.md
Expanded pre-submit wording to require running multiple commands and to include their outputs; command list changed from make audit to make audit, make generate, make betteralign, make modernize, make format, make test. Applied in two sections.
Client transport abstraction
client/transport.go
New internal transport interface and adapters for fasthttp.Client, fasthttp.HostClient, and fasthttp.LBClient; implements Do/DoTimeout/DoDeadline/DoRedirects, CloseIdleConnections, TLSConfig/SetTLSConfig, SetDial, Client accessors; utilities to walk nested LB clients and extract/apply TLS and dial settings; redirect handling and URL composition helpers.
Client API migration to transport
client/client.go
Replaced direct fasthttp field with transport-backed httpClientTransport; added Client methods delegating to transport (Do, DoTimeout, DoDeadline, DoRedirects, CloseIdleConnections); added constructors NewWithHostClient/NewWithLBClient and accessors for underlying fasthttp clients; TLS/proxy/dial plumbing now routed through transport wrappers; constructors/Reset refactored to use transport helpers.
Core integration
client/core.go
Replaced direct calls to fasthttp methods with corresponding Client.Do / Client.DoRedirects wrapper calls in retry and non-retry paths.
Transport tests
client/transport_test.go
New comprehensive tests with stubs/wrappers covering Do/Timeout/Deadline/DoRedirects, redirect branches/limits, TLS extraction/propagation, nested LB traversal, and dial/TLS overrides across layers.
Client tests expansion
client/client_test.go
Expanded tests validating HostClient/LBClient constructors, transport wiring, redirect/retry interactions, TLS/proxy/dial propagation, reset/idle/timeout behavior, marshal hooks, and end-to-end scenarios against a test server.
Docs: client examples
docs/client/examples.md
Added examples showing wrapping fasthttp.HostClient and fasthttp.LBClient with client.NewWithHostClient/client.NewWithLBClient, demonstrating TLS/timeouts and noting shared overrides across LB-managed host clients.
Docs: what's new
docs/whats_new.md
Documented the new transport integration and constructors, propagation of dialer/TLS/proxy settings into LB-managed host clients, and new client surface methods (Do, DoTimeout, DoDeadline, CloseIdleConnections).
Docs: client rest
docs/client/rest.md
Minor doc clarifications: TLS MinVersion default note and Reset description.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App as Application
  participant C as client.Client
  participant T as Transport (interface)
  participant FH as fasthttp.* (Client/HostClient/LBClient)

  App->>C: C.Do(req, resp)
  activate C
  C->>T: Do(req, resp)
  activate T
  T->>FH: Do(req, resp)
  activate FH
  FH-->>T: success / error
  deactivate FH
  T-->>C: success / error
  deactivate T
  C-->>App: success / error
  deactivate C
  note over C,T: TLS/Proxy/Dial applied via transport
Loading
sequenceDiagram
  autonumber
  participant App as Application
  participant C as client.Client
  participant T as LB Transport
  participant LB as fasthttp.LBClient
  participant HC as HostClient (n)
  participant S as Server

  App->>C: C.DoRedirects(req, resp, max)
  activate C
  C->>T: DoRedirects(...)
  activate T
  T->>LB: Do(req, resp)
  activate LB
  LB->>HC: select HostClient
  activate HC
  HC->>S: HTTP request
  S-->>HC: 3xx + Location
  deactivate HC
  LB-->>T: response
  deactivate LB
  alt redirects remaining
    T->>T: composeRedirectURL(...)
    T->>LB: Do(nextReq, resp)
  else limit reached / invalid
    T-->>C: error
  end
  deactivate T
  C-->>App: success / error
  deactivate C
  note over T,LB: Dial/TLS propagated to all HostClients
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • sixcolors
  • efectn
  • ReneWerner87

Poem

I hop through hosts with balanced grace,
New routes I map, redirects I chase.
TLS in paw, dials aligned,
Through fibered paths, our calls refined.
Make, test, and thump—checks all green. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The modifications to AGENTS.md introduce programmatic check guidance unrelated to the goal of adding HostClient and LBClient support, indicating out-of-scope changes outside the linked issue’s proposal. Remove or separate the AGENTS.md updates into a dedicated pull request and keep this pull request focused solely on the transport abstraction and support for HostClient and LBClient.
Description Check ⚠️ Warning The pull request description only provides a brief summary and a linked issue reference but omits required sections from the repository template, such as detailed “Changes introduced,” documentation updates, changelog entries, migration guidance, type of change, and the completion checklist, failing to follow the prescribed structure. Please update the pull request description to follow the repository’s template by adding a “Changes introduced” section listing features and adjustments, documenting updates and changelog entries, specifying the type of change, and completing the provided checklist items including benchmarks, documentation updates, migration guides, and tests.
Docstring Coverage ⚠️ Warning Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title concisely highlights the main enhancement by stating support for HostClient and LBClient within the Fiber client, clearly summarizing the primary change and adhering to conventional commit style while remaining brief.
Linked Issues Check ✅ Passed All changes directly address the objectives of issue #3232 by abstracting the transport layer to support fasthttp.HostClient and fasthttp.LBClient, including constructor enhancements, client method updates, transport adapters, comprehensive tests, and corresponding documentation examples.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-client.client-for-fasthttp-compatibility

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gaby gaby changed the title Consolidate client test files 🔥 feat: Add support for HostClient and LBClient Oct 2, 2025
@gaby
Copy link
Member Author

gaby commented Oct 2, 2025

/gemini review

@codecov
Copy link

codecov bot commented Oct 2, 2025

Codecov Report

❌ Patch coverage is 95.65217% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.08%. Comparing base (a3c54bb) to head (2a2d012).
⚠️ Report is 22 commits behind head on main.

Files with missing lines Patch % Lines
client/transport.go 94.57% 6 Missing and 3 partials ⚠️
client/core.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3774      +/-   ##
==========================================
+ Coverage   91.67%   92.08%   +0.40%     
==========================================
  Files         113      114       +1     
  Lines       11959    12182     +223     
==========================================
+ Hits        10964    11218     +254     
+ Misses        731      702      -29     
+ Partials      264      262       -2     
Flag Coverage Δ
unittests 92.08% <95.65%> (+0.40%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and valuable refactoring by abstracting the underlying fasthttp client, allowing the Fiber client to work with fasthttp.Client, fasthttp.HostClient, and fasthttp.LBClient. This greatly increases flexibility for users who want to reuse existing fasthttp transport configurations. The implementation is solid and well-tested. I've provided a few suggestions to improve maintainability and fix a potential issue with nested load balancers.

@gaby
Copy link
Member Author

gaby commented Oct 2, 2025

@codex create a list of task/fixes for an ai agent based on the comments from gemini-code-assist in this pull request.

@chatgpt-codex-connector
Copy link

Summary

  • Added GEMINI_TASKS.md describing the Gemini Code Assist follow-up items for recursive load balancer handling, client wrapper cleanup, and TLS configuration simplification. GEMINI_TASKS.mdL1-L6

Testing

  • ⚠️ No tests were run (not requested).

View task →

@gaby
Copy link
Member Author

gaby commented Oct 2, 2025

/gemini review

@gaby gaby requested a review from Copilot October 2, 2025 03:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for integrating existing fasthttp.HostClient and fasthttp.LBClient instances with the Fiber client, allowing users to reuse custom connection pools, load balancing logic, and transport configurations while maintaining Fiber's retry, redirect, and hook functionality.

Key changes:

  • Introduces NewWithHostClient() and NewWithLBClient() constructor functions
  • Implements a transport abstraction layer to unify handling of different fasthttp client types
  • Adds comprehensive test coverage for the new transport functionality

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
client/transport.go Core transport abstraction with implementations for standard, host, and load balancer clients
client/transport_test.go Comprehensive test coverage for all transport implementations and edge cases
client/client.go Updated client structure to use transport abstraction and new constructor functions
client/client_test.go Integration tests for new client constructors and transport behaviors
client/core.go Updated to use transport interface methods instead of direct fasthttp client access
docs/client/examples.md Documentation examples showing usage of new HostClient and LBClient features
docs/whats_new.md Release notes documenting the new fasthttp transport integration features

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and well-designed feature to support fasthttp.HostClient and fasthttp.LBClient, abstracting the transport layer of the Fiber client. The changes are extensive, including refactoring the client, adding new constructors, and providing comprehensive tests. The abstraction allows for greater flexibility and reuse of existing fasthttp client configurations. I've found one critical issue in the custom redirect handling logic for LBClient that should be addressed.

@gaby
Copy link
Member Author

gaby commented Oct 2, 2025

@codex create a list of task/fixes for an ai agent based on the comments from gemini-code-assist and copilot on this pull request and all the errors from the golangci-lint ci pipeline

@chatgpt-codex-connector
Copy link

Summary

  • Added AI_AGENT_TASKS.md to catalog Gemini Code Assist follow-ups, Copilot review fixes, and the golangci-lint toolchain mismatch that still need attention. AI_AGENT_TASKS.mdL1-L12

Testing

  • make lint (fails because golangci-lint was built with Go 1.24 while the config targets Go 1.25)

View task →

@gaby
Copy link
Member Author

gaby commented Oct 2, 2025

/gemini review

@gaby gaby requested a review from Copilot October 2, 2025 21:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant enhancement to the Fiber client by adding support for fasthttp.HostClient and fasthttp.LBClient. This is achieved by abstracting the transport layer into a httpClientTransport interface, with implementations for the standard fasthttp.Client, HostClient, and LBClient. The changes are well-structured, include comprehensive tests, and update the documentation. My review found one minor inconsistency in the redirect handling for LBClient that could be improved for better behavioral consistency with other client types.

@gaby
Copy link
Member Author

gaby commented Oct 2, 2025

@codex create a list of unresolved issues raised for an ai agent to fix them

@chatgpt-codex-connector
Copy link

Summary

  • Documented outstanding redirect-handling and security follow-ups for the fasthttp transport layer in AI_AGENT_UNRESOLVED.md, consolidating unresolved Gemini and Copilot review items. AI_AGENT_UNRESOLVED.mdL1-L14

Testing

  • ⚠️ No tests were run (not requested).

View task →

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a well-designed transport abstraction to support fasthttp.HostClient and fasthttp.LBClient, which is a valuable addition to the Fiber client. The implementation is thorough and includes extensive test coverage for the new functionality. However, I've identified a critical issue in the handling of tls.Config within the new transport layer. The TLSConfig() methods incorrectly return a clone, which prevents methods like SetCertificates from working as expected. I've provided a detailed comment with a suggested fix and pointed out the corresponding tests that will need to be updated. Once this is addressed, this will be an excellent contribution.

@gaby gaby marked this pull request as ready for review October 10, 2025 12:40
@gaby gaby requested a review from a team as a code owner October 10, 2025 12:40
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
client/client_test.go (1)

2133-2167: Leak: proxyServer isn’t shut down

proxyServer is started but never stopped. Add a cleanup to call proxyServer.Shutdown() to prevent goroutine/resource leaks across tests.

 proxyServer := fiber.New()
 // ... start proxyServer in a goroutine
+t.Cleanup(func() {
+    require.NoError(t, proxyServer.Shutdown())
+})
♻️ Duplicate comments (7)
client/client_test.go (2)

385-389: Replace fixed sleeps with readiness polling (TLS servers)

Fixed time.Sleep(1 * time.Second) is flaky. Poll the TLS listener until it accepts connections.

// Replace time.Sleep with a small polling loop:
addr := ln.Addr().String()
deadline := time.Now().Add(3 * time.Second)
for {
    conn, err := tls.Dial("tcp", addr, clientTLSConf)
    if err == nil {
        _ = conn.Close()
        break
    }
    if time.Now().After(deadline) {
        t.Fatalf("server not ready within deadline: %v", err)
    }
    time.Sleep(50 * time.Millisecond)
}

Also applies to: 551-555


1849-1849: TLS config identity assertions are correct

Using require.Same avoids deep-equality pitfalls on *tls.Config and validates the returned instance is the active one.

Also applies to: 1884-1884, 565-565

client/transport.go (3)

299-303: Name magic numbers in control-char check (optionally expand to C1 controls)

Use named constants for 0x20 and 0x7f for clarity. Optionally reject C1 controls (0x80–0x9f).

Apply this diff:

@@
-// defaultRedirectLimit mirrors fasthttp's default when callers supply a negative redirect cap.
+// defaultRedirectLimit mirrors fasthttp's default when callers supply a negative redirect cap.
 const defaultRedirectLimit = 16
+
+// ASCII control ranges used for URI validation.
+const (
+	minPrintableASCII = 0x20
+	delASCII          = 0x7f
+)
@@
-	for _, b := range location {
-		if b < 0x20 || b == 0x7f {
+	for _, b := range location {
+		if b < minPrintableASCII || b == delASCII {
 			return "", fasthttp.ErrorInvalidURI
 		}
 	}

Optionally:

-		if b < minPrintableASCII || b == delASCII {
+		if b < minPrintableASCII || b == delASCII || (b >= 0x80 && b <= 0x9f) {

181-188: Recursive traversal of nested LBClient/HostClient is correct

walkBalancingClient delegates to walkBalancingClientWithBreak and the latter correctly recurses through LBClient and wrapper types exposing LBClient(). This addresses prior review feedback.

Also applies to: 209-230


246-267: Redirect behavior for maxRedirects <= 0 aligns with fasthttp

singleRequestOnly path returns the initial response (which may be a redirect) without error, matching fasthttp.Client/HostClient semantics.

client/transport_test.go (2)

339-342: Nit: unused loop index

Use _ since the index isn’t used.

-	for i := 0; i < defaultRedirectLimit+1; i++ {
+	for _ := 0; _ < defaultRedirectLimit+1; _++ {

266-284: Good: 303 See Other behavior covered

Tests assert POST→GET, body cleared, and content headers removed for 303. This prevents regressions.

🧹 Nitpick comments (7)
docs/whats_new.md (1)

777-782: Clarify usage and cross-link examples for HostClient/LBClient

Add a note on HostClient.Addr formatting and link to the examples section to reduce misconfiguration.

Apply this doc tweak:

 ### Fasthttp transport integration

 - `client.NewWithHostClient` and `client.NewWithLBClient` allow you to plug existing `fasthttp` clients directly into Fiber while keeping retries, redirects, and hook logic consistent.
 - Dialer, TLS, and proxy helpers now update every host client inside a load balancer, so complex pools inherit the same configuration.
 - The Fiber client exposes `Do`, `DoTimeout`, `DoDeadline`, and `CloseIdleConnections`, matching the surface area of the wrapped fasthttp transports.
+ - When using `fasthttp.HostClient`, remember that `HostClient.Addr` must be `host:port` (no scheme), and HTTPS endpoints require `IsTLS=true`. See examples in [Reusing fasthttp transports](./client/examples.md#reusing-fasthttp-transports).
AGENTS.md (1)

50-52: Include linting in required programmatic checks

Per repo guidelines, golangci-lint is enforced via make lint. Add it to the must-run list.

 Before presenting final changes or submitting a pull request, run each of the
 following commands and ensure they succeed. Include the command outputs in your
 final response to confirm they were executed:
 ```bash
 make audit
+make lint
 make generate
 make betteralign
 make modernize
 make format
 make test

</blockquote></details>
<details>
<summary>docs/client/examples.md (2)</summary><blockquote>

`162-190`: **Prevent response leaks and clarify HostClient.Addr**

- Add `defer resp.Close()` to release pooled buffers.
- Note that `HostClient.Addr` must be `host:port` (no scheme); set `IsTLS=true` for HTTPS.



```diff
 func main() {
     hc := &fasthttp.HostClient{
-        Addr:              "api.internal:443",
+        Addr:              "api.internal:443", // host:port, no scheme
         IsTLS:             true,
         MaxConnDuration:   30 * time.Second,
         MaxIdleConnDuration: 10 * time.Second,
     }

     cc := client.NewWithHostClient(hc)

-    resp, err := cc.Get("https://api.internal:443/status")
+    resp, err := cc.Get("https://api.internal:443/status")
     if err != nil {
         log.Fatal(err)
     }
+    defer resp.Close()

     log.Printf("status=%d body=%s", resp.StatusCode(), resp.Body())
 }

205-225: Add response close in LB example

Release response resources to avoid test/doc copy-paste leaks.

     resp, err := cc.Get("http://service.internal/api")
     if err != nil {
         log.Fatal(err)
     }
+    defer resp.Close()

     log.Printf("status=%d body=%s", resp.StatusCode(), resp.Body())
client/client_test.go (1)

1083-1084: Remove unnecessary sleeps after startTestServerWithPort

startTestServerWithPort already signals readiness via ListenerAddrFunc. These sleeps slow tests and add flakiness; they can be removed safely.

- time.Sleep(1 * time.Second)

Also applies to: 1192-1193

client/transport.go (1)

150-156: Simplify TLSConfig: redundant empty check

extractTLSConfig already returns nil for empty slices; the len(...) == 0 guard is unnecessary.

-func (l *lbClientTransport) TLSConfig() *tls.Config {
-	if len(l.client.Clients) == 0 {
-		return nil
-	}
-	return extractTLSConfig(l.client.Clients)
-}
+func (l *lbClientTransport) TLSConfig() *tls.Config {
+	return extractTLSConfig(l.client.Clients)
+}
client/transport_test.go (1)

253-326: Add test for cross-host auth stripping if you adopt the redirect security change

If you implement dropping Authorization on cross-host redirect, add a case asserting the header is removed when Location points to a different host.

t.Run("drop auth on cross-host redirect", func(t *testing.T) {
  req.Reset(); resp.Reset()
  req.SetRequestURI("http://example.com/start")
  req.Header.SetMethod(fasthttp.MethodGet)
  req.Header.Set(fasthttp.HeaderAuthorization, "Bearer secret")
  client := &stubRedirectClient{calls: []stubRedirectCall{
    {status: ptrInt(fasthttp.StatusFound), location: ptrString("http://other.com/next")},
    {status: ptrInt(fasthttp.StatusOK)},
  }}
  require.NoError(t, doRedirectsWithClient(req, resp, 2, client))
  require.Empty(t, req.Header.Peek(fasthttp.HeaderAuthorization))
  require.Equal(t, "http://other.com/next", req.URI().String())
})
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3c54bb and 73f97d2.

📒 Files selected for processing (8)
  • AGENTS.md (1 hunks)
  • client/client.go (7 hunks)
  • client/client_test.go (5 hunks)
  • client/core.go (1 hunks)
  • client/transport.go (1 hunks)
  • client/transport_test.go (1 hunks)
  • docs/client/examples.md (1 hunks)
  • docs/whats_new.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/whats_new.md
  • docs/client/examples.md
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • client/transport_test.go
  • client/core.go
  • client/transport.go
  • client/client.go
  • client/client_test.go
🧠 Learnings (3)
📚 Learning: 2025-09-01T07:16:43.444Z
Learnt from: CR
PR: gofiber/fiber#0
File: AGENTS.md:0-0
Timestamp: 2025-09-01T07:16:43.444Z
Learning: Before submitting a PR with generated changes, run and pass: `make audit`, `make generate`, `make betteralign`, `make modernize`, `make format`, and `make test`

Applied to files:

  • AGENTS.md
📚 Learning: 2024-11-29T12:37:27.581Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: app_test.go:893-895
Timestamp: 2024-11-29T12:37:27.581Z
Learning: In the `Test_App_ShutdownWithContext` function in `app_test.go`, the `clientDone` channel is used to synchronize the client's request completion before proceeding, eliminating the need for additional `time.Sleep` calls.

Applied to files:

  • client/client_test.go
📚 Learning: 2024-09-25T17:05:06.991Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/middleware_test.go:190-191
Timestamp: 2024-09-25T17:05:06.991Z
Learning: When testing session `IdleTimeout` expiration, it's acceptable to use `time.Sleep` to simulate the passage of time in tests.

Applied to files:

  • client/client_test.go
🧬 Code graph analysis (4)
client/core.go (1)
middleware/proxy/proxy.go (2)
  • DoRedirects (144-148)
  • Do (135-139)
client/transport.go (2)
middleware/proxy/proxy.go (4)
  • Do (135-139)
  • DoTimeout (160-164)
  • DoDeadline (152-156)
  • DoRedirects (144-148)
client/client.go (2)
  • Config (625-639)
  • Client (32-62)
client/client.go (2)
middleware/proxy/proxy.go (4)
  • Do (135-139)
  • DoTimeout (160-164)
  • DoDeadline (152-156)
  • DoRedirects (144-148)
middleware/proxy/config.go (1)
  • Config (12-70)
client/client_test.go (4)
client/client.go (5)
  • NewWithHostClient (731-736)
  • NewWithLBClient (739-744)
  • New (715-720)
  • Get (794-796)
  • Config (625-639)
log/fiberlog.go (1)
  • WithContext (122-124)
client/cookiejar.go (1)
  • AcquireCookieJar (23-30)
internal/tlstest/tls.go (1)
  • GetTLSConfigs (18-120)
🪛 GitHub Check: CodeQL
client/transport.go

[failure] 254-254: Uncontrolled data used in network request
The URL of this request depends on a user-provided value.
The URL of this request depends on a user-provided value.

🔇 Additional comments (4)
client/core.go (1)

96-99: LGTM: delegate to transport-aware Do/DoRedirects

Switching to c.client.Do* correctly routes calls through the new transport layer (standard/Host/LB). Matches the PR’s abstraction goals.

Also applies to: 102-105

client/client_test.go (1)

239-257: Reset behavior assertions look good

Verifies reset switches transport back to standard client and clears client state. Matches intended semantics.

client/transport.go (1)

253-258: CodeQL: Uncontrolled data used in network request — confirm mitigations

Static analysis flags setting RequestURI from a variable. Here:

  • Initial URL comes from req.URI().String() (same request),
  • Redirect targets are validated by composeRedirectURL (rejects control chars, enforces http/https, and requires host when scheme is present).

If desired, further harden by limiting max URL length or rejecting userinfo in Location. Consider documenting this rationale to suppress the alert.

Based on static analysis hints

client/client.go (1)

722-729: Constructors and Reset refactor look solid

  • NewWithClient/HostClient/LBClient nil-guard and transport wiring: OK.
  • Reset resetting to standard transport ensures a usable default state.

Also applies to: 730-745, 746-770

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
client/client.go (1)

604-623: Missing mutex protection in Reset.

Reset replaces c.transport (line 605) and mutates other client state without acquiring c.mu. Other mutating methods (SetRetryConfig, SetDial, SetProxyURL, SetLogger) all lock the mutex. If Reset is called concurrently with active requests or setters, races can occur.

Apply this diff to add mutex protection:

 func (c *Client) Reset() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+
 	c.transport = newStandardClientTransport(&fasthttp.Client{})
 	c.baseURL = ""
 	c.timeout = 0
 	c.userAgent = ""
 	c.referer = ""
 	c.retryConfig = nil
 	c.debug = false
 	c.disablePathNormalizing = false

 	if c.cookieJar != nil {
 		c.cookieJar.Release()
 		c.cookieJar = nil
 	}

 	c.path.Reset()
 	c.cookies.Reset()
 	c.header.Reset()
 	c.params.Reset()
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73f97d2 and e407c36.

📒 Files selected for processing (1)
  • client/client.go (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • client/client.go
🧬 Code graph analysis (1)
client/client.go (4)
middleware/proxy/proxy.go (4)
  • Do (135-139)
  • DoTimeout (160-164)
  • DoDeadline (152-156)
  • DoRedirects (144-148)
client/request.go (1)
  • Request (46-73)
client/response.go (1)
  • Response (19-25)
middleware/proxy/config.go (1)
  • Config (12-70)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Compare
  • GitHub Check: repeated
🔇 Additional comments (6)
client/client.go (6)

33-34: LGTM: Transport abstraction cleanly replaces direct fasthttp client.

The new transport httpClientTransport field successfully abstracts the underlying client type, enabling support for HostClient and LBClient as intended.


64-92: LGTM: Transport delegation methods are clean and well-documented.

The new Do, DoTimeout, DoDeadline, DoRedirects, and CloseIdleConnections methods correctly delegate to the underlying transport, mirroring fasthttp behavior.


94-104: LGTM: Helper methods cleanly abstract transport operations.

The unexported helpers currentTLSConfig, applyTLSConfig, and applyDial appropriately route configuration to the transport.


106-128: LGTM: Accessor methods appropriately expose underlying clients.

FasthttpClient, HostClient, and LBClient use type assertions to return the underlying transport when it matches the expected type, returning nil otherwise. This is a reasonable pattern.


298-304: LGTM: Mutex protection added, addressing prior review comment.

The mutex lock on lines 300-301 resolves the race condition flagged in a previous review by coderabbitai, aligning SetProxyURL with the locking pattern used in SetDial.


725-747: LGTM: New constructors cleanly wrap HostClient and LBClient.

The updated NewWithClient and new NewWithHostClient/NewWithLBClient constructors consistently use the transport abstraction and panic on nil inputs, which is appropriate for constructors.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
client/client.go (1)

106-128: Document nil return behavior for clarity.

The accessor methods correctly return the underlying client when the transport type matches, but the nil return case when types don't match could be better documented for API clarity.

Consider adding documentation like:

 // FasthttpClient returns the underlying *fasthttp.Client if the client was created with one.
+// Returns nil if the client was created with NewWithHostClient or NewWithLBClient.
 func (c *Client) FasthttpClient() *fasthttp.Client {

Apply similar documentation to HostClient and LBClient.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e407c36 and d1ce554.

📒 Files selected for processing (1)
  • client/client.go (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • client/client.go
🧬 Code graph analysis (1)
client/client.go (4)
middleware/proxy/proxy.go (4)
  • Do (135-139)
  • DoTimeout (160-164)
  • DoDeadline (152-156)
  • DoRedirects (144-148)
client/request.go (1)
  • Request (46-73)
client/response.go (1)
  • Response (19-25)
middleware/proxy/config.go (1)
  • Config (12-70)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: Compare
  • GitHub Check: repeated
🔇 Additional comments (7)
client/client.go (7)

64-92: LGTM! Clean transport delegation.

The new methods properly delegate request execution and lifecycle operations to the underlying transport, enabling support for different fasthttp client types while maintaining a consistent API.


94-104: LGTM! Proper transport abstraction.

The helper methods cleanly abstract TLS and dial operations, and all call sites properly acquire the client mutex before invoking these methods.


231-241: LGTM! Race condition fixed.

The mutex protection properly addresses the race condition flagged in previous reviews, ensuring the read-check-write sequence is atomic.


244-250: LGTM! Mutex protection added.

The mutex protection addresses the inconsistency flagged in previous reviews and aligns with the locking pattern used in other transport-mutating methods.


304-311: LGTM! Data race risk mitigated.

The mutex protection addresses the data race risk flagged in previous reviews and maintains consistency with other transport-mutating methods.


610-629: LGTM! Reset properly restores default state.

The method now correctly restores the client to a default standardClientTransport as recommended in previous reviews, ensuring the client is always in a known, usable state after reset.


732-779: LGTM! Constructors properly support all client types.

The new constructors successfully enable the use of fasthttp.HostClient and fasthttp.LBClient as requested in the linked issue #3232, while maintaining API consistency through the shared newClient helper and uniform nil-check behavior.

@gaby gaby requested a review from Copilot October 11, 2025 01:26
@gaby
Copy link
Member Author

gaby commented Oct 11, 2025

@coderabbitai review

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
client/client.go (1)

614-636: Add mutex protection to prevent races during Reset.

The Reset method modifies c.transport (line 618) and other shared state without acquiring c.mu, but methods like SetTLSConfig (lines 250-251), SetDial (lines 593-594), and SetProxyURL (lines 311-312) all lock the mutex before accessing c.transport. This creates a race condition if Reset is called concurrently with these configuration methods.

Apply this diff to add mutex protection:

 func (c *Client) Reset() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+
 	c.transport = newStandardClientTransport(&fasthttp.Client{})
 	c.baseURL = ""
 	c.timeout = 0
🧹 Nitpick comments (2)
client/client.go (2)

309-316: Consider documenting the error return or making it infallible.

SetProxyURL always returns nil, suggesting the error return is unused. If errors are not possible with the current implementation, consider either:

  1. Documenting why the error return exists (e.g., for future extensibility or API compatibility), or
  2. Changing the signature to remove the error return if it's not needed.

For reference, if the error return is truly unused and won't be needed in the future, you could simplify to:

-func (c *Client) SetProxyURL(proxyURL string) error {
+func (c *Client) SetProxyURL(proxyURL string) *Client {
 	c.mu.Lock()
 	defer c.mu.Unlock()
 
 	c.applyDial(fasthttpproxy.FasthttpHTTPDialer(proxyURL))
-	return nil
+	return c
 }

This would also make it consistent with other setter methods that return *Client for chaining.


738-744: Consider clarifying transport type in documentation.

The documentation could be slightly more explicit by mentioning that this creates a client with a "standard client transport" to align with internal naming conventions and help users understand which transport type is being used.

Based on learnings from past review comments.

Example enhancement:

-// NewWithClient creates and returns a new Client object from an existing fasthttp.Client.
+// NewWithClient creates and returns a new Client object from an existing fasthttp.Client,
+// wrapping it in a standard client transport for general-purpose HTTP requests.
 func NewWithClient(c *fasthttp.Client) *Client {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1ce554 and 2a2d012.

📒 Files selected for processing (4)
  • client/client.go (8 hunks)
  • client/core.go (2 hunks)
  • client/transport.go (1 hunks)
  • docs/client/rest.md (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs/client/rest.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • client/core.go
  • client/transport.go
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • client/client.go
🧬 Code graph analysis (1)
client/client.go (3)
middleware/proxy/proxy.go (4)
  • Do (135-139)
  • DoTimeout (160-164)
  • DoDeadline (152-156)
  • DoRedirects (144-148)
client/request.go (1)
  • Request (46-73)
client/response.go (1)
  • Response (19-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: repeated
  • GitHub Check: Compare
🔇 Additional comments (1)
client/client.go (1)

746-786: LGTM! New constructors and initialization are well-implemented.

The new NewWithHostClient and NewWithLBClient constructors follow the same safe pattern as NewWithClient (nil checks with panic on invalid input, delegation to transport-specific wrappers). The newClient helper function provides consistent initialization across all transport types, setting up sensible defaults for marshaling, hooks, and other client features.

@ReneWerner87 ReneWerner87 merged commit a167c6f into main Oct 13, 2025
15 checks passed
@ReneWerner87 ReneWerner87 deleted the refactor-client.client-for-fasthttp-compatibility branch October 13, 2025 09:32
@github-project-automation github-project-automation bot moved this from In Progress to Done in v3 Oct 13, 2025
laughing-nerd pushed a commit to laughing-nerd/fiber that referenced this pull request Oct 13, 2025
Abhirup-99 pushed a commit to Abhirup-99/fiber that referenced this pull request Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

📝 [Proposal]: Add support for fasthttp.HostClient

4 participants