🔥 feat: Add support for HostClient and LBClient#3774
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughAdds an internal transport abstraction for the Fiber HTTP client to wrap Changes
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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
/gemini review |
Codecov Report❌ Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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.
|
@codex create a list of task/fixes for an ai agent based on the comments from gemini-code-assist in this pull request. |
|
Summary
Testing
|
|
/gemini review |
There was a problem hiding this comment.
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()andNewWithLBClient()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 |
There was a problem hiding this comment.
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.
|
@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 |
|
Summary
Testing
|
|
/gemini review |
There was a problem hiding this comment.
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.
|
@codex create a list of unresolved issues raised for an ai agent to fix them |
|
Summary
Testing
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
proxyServeris started but never stopped. Add a cleanup to callproxyServer.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 correctUsing
require.Sameavoids deep-equality pitfalls on*tls.Configand 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 correctwalkBalancingClient 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 fasthttpsingleRequestOnly 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 indexUse
_since the index isn’t used.- for i := 0; i < defaultRedirectLimit+1; i++ { + for _ := 0; _ < defaultRedirectLimit+1; _++ {
266-284: Good: 303 See Other behavior coveredTests 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/LBClientAdd 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 checksPer 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 exampleRelease 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
startTestServerWithPortalready signals readiness viaListenerAddrFunc. 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 checkextractTLSConfig 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 changeIf 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
📒 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
docsfolder if necessary when modifying code
Files:
docs/whats_new.mddocs/client/examples.md
**/*.go
📄 CodeRabbit inference engine (AGENTS.md)
**/*.go: Format Go code using gofumpt (enforced viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake modernize)
Files:
client/transport_test.goclient/core.goclient/transport.goclient/client.goclient/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/DoRedirectsSwitching 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 goodVerifies 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 mitigationsStatic 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
There was a problem hiding this comment.
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.
Resetreplacesc.transport(line 605) and mutates other client state without acquiringc.mu. Other mutating methods (SetRetryConfig, SetDial, SetProxyURL, SetLogger) all lock the mutex. IfResetis 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
📒 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 viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake 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 httpClientTransportfield 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, andapplyDialappropriately 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
SetProxyURLwith the locking pattern used inSetDial.
725-747: LGTM: New constructors cleanly wrap HostClient and LBClient.The updated
NewWithClientand newNewWithHostClient/NewWithLBClientconstructors consistently use the transport abstraction and panic on nil inputs, which is appropriate for constructors.
There was a problem hiding this comment.
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
HostClientandLBClient.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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 viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake 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
standardClientTransportas 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.HostClientandfasthttp.LBClientas requested in the linked issue #3232, while maintaining API consistency through the sharednewClienthelper and uniform nil-check behavior.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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
Resetmethod modifiesc.transport(line 618) and other shared state without acquiringc.mu, but methods likeSetTLSConfig(lines 250-251),SetDial(lines 593-594), andSetProxyURL(lines 311-312) all lock the mutex before accessingc.transport. This creates a race condition ifResetis 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.
SetProxyURLalways returnsnil, suggesting the error return is unused. If errors are not possible with the current implementation, consider either:
- Documenting why the error return exists (e.g., for future extensibility or API compatibility), or
- 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
*Clientfor 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
📒 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 viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake 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
NewWithHostClientandNewWithLBClientconstructors follow the same safe pattern asNewWithClient(nil checks with panic on invalid input, delegation to transport-specific wrappers). ThenewClienthelper function provides consistent initialization across all transport types, setting up sensible defaults for marshaling, hooks, and other client features.
Summary
fasthttp.HostClientandfasthttp.LBClientin the Fiber client, abstracting the transport layer to accommodate differentfasthttpclient types.Fixes #3232