valyala/fasthttp

Client: add DoContext method for context.Context-aware request execution

Open

#2198 opened on May 1, 2026

View on GitHub
 (0 comments) (0 reactions) (0 assignees)Go (21,741 stars) (1,755 forks)batch import
feature requesthelp wanted

Description

Feature Request

Is your feature request related to a problem? Please describe.

The fasthttp client provides DoTimeout() and DoDeadline(), but lacks a DoContext(ctx context.Context, req, resp) method. This means:

  1. No cancellation propagation: If a parent context is cancelled (e.g., an HTTP handler's ctx.Done()), the in-flight fasthttp request continues until its own timeout or completion.
  2. No deadline inheritance: If a caller has an existing context with a deadline (e.g., from gRPC or an upstream request), there's no way to pass it through.
  3. No metadata attachment: Tracing systems (OpenTelemetry, etc.) rely on context to propagate trace IDs.

This forces users to either:

  • Use net/http (which has Client.Do(req.WithContext(ctx))) and lose performance
  • Manually create a context.WithTimeout and call DoDeadline, losing parent cancellation

Describe the solution you'd like

Add a DoContext method to both Client and HostClient:

func (c *Client) DoContext(ctx context.Context, req *Request, resp *Response) error
func (c *HostClient) DoContext(ctx context.Context, req *Request, resp *Response) error

Behavior:

  • If ctx is already cancelled, return ctx.Err() immediately
  • If ctx has a deadline, use it (respecting any existing timeout set on the Client)
  • If the context is cancelled during dial, reading, or writing, abort the operation and return ctx.Err()
  • The implementation can reuse the existing timeout/deadline logic in the TCP dialer, which already uses context.Context internally

Describe alternatives you've considered

  • Using DoDeadline with ctx.Deadline() — works but loses cancellation propagation (only deadline is respected, not ctx.Done())
  • Wrapping DoTimeout in a goroutine with select { case <-ctx.Done() } — racy, doesn't actually cancel the underlying I/O
  • Using net/http — defeats the purpose of using fasthttp

Additional context

  • The internal tcpdialer already uses context.Context for DNS resolution (Resolver.LookupIPAddr(ctx, host))
  • Server.ShutdownWithContext(ctx) already exists, showing the project embraces context for lifecycle management
  • Other Go HTTP clients (net/http, resty, go-resty) all support context-aware requests

Contributor guide