Few notes about fiber adapter
If i understand correctly fiberCtx.SetReadDeadline actually doesn't work and probably will not. Also if at same time we will add ability to get client IP address from huma.Context it will not work with current fiber adapter implementation.
Currently fiberAdapter.ServeHTTP calls App.Test to handle requests. This method uses testConn to mock incoming connection.
But testConn.Set*Deadline methods do nothing (source):
func (*testConn) SetDeadline(_ time.Time) error { return nil }
func (*testConn) SetReadDeadline(_ time.Time) error { return nil }
func (*testConn) SetWriteDeadline(_ time.Time) error { return nil }
And testConn.*Addr methods return hardcoded values (source):
func (*testConn) LocalAddr() net.Addr { return &net.TCPAddr{Port: 0, Zone: "", IP: net.IPv4zero} }
func (*testConn) RemoteAddr() net.Addr { return &net.TCPAddr{Port: 0, Zone: "", IP: net.IPv4zero} }
About using adaptor middleware
Closure returned by adaptor.handlerFunc serves as fiberAdapter.ServeHTTP, it declares fctx variable and initialize it by calling RequestCtx.Init method.
func handlerFunc(app *fiber.App, h ...fiber.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// ...
var fctx fasthttp.RequestCtx
fctx.Init(req, remoteAddr, nil)
RequestCtx.Init method calls RequestCtx.Init2 passing fakeAddrer struct as net.Conn value without setting underlying net.Conn to anything
func (ctx *RequestCtx) Init(req *Request, remoteAddr net.Addr, logger Logger) {
// ...
c := &fakeAddrer{
laddr: zeroTCPAddr,
raddr: remoteAddr,
}
// ...
ctx.Init2(c, logger, true)
// ...
}
// ...
type fakeAddrer struct {
net.Conn
laddr net.Addr
raddr net.Addr
}
RequestCtx.Init2 sets c field to provided net.Conn value
func (ctx *RequestCtx) Init2(conn net.Conn, logger Logger, reduceMemoryUsage bool) {
ctx.c = conn
RequestCtx.Conn returns it's c property value (fakeAddrer with underlying net.Conn set to nil)
func (ctx *RequestCtx) Conn() net.Conn {
return ctx.c
}
fakeAddrer doesn't have it's own SetReadDeadline implementation so it calls SetReadDeadline method of it's underlying net.Conn (nil), because of that c.orig.Context().Conn().SetReadDeadline(deadline) in fiberCtx.SetReadDeadline panics.
IMHO: We can simply return nil from fiberCtx.SetReadDeadline without doing anything because it will not work anyway.
@x-user hello!
I am maintaing humafiber adapter (not officially). I read your issue and comment, and I want to drag your attention to the following:
- fasthttp and fiber has the very special way to deal with context (because of zero-allocation)
- fiber.Ctx.Context and fiber.Ctx.UserContext works in the very specific way.
The long story short - to get expected behavior with Deadline, you need to alter "UserContext" inside middleware and you should use "UserContext" with altering to get it.
Take a look to this article from fiber documentation about timeout
- https://docs.gofiber.io/api/middleware/timeout/
Also you could take a look to this pull request with fixes to huma.Context <=> Fiber integration
- https://github.com/danielgtaylor/huma/pull/725
Bottom line - use fiber "Timeout" middleware + fixed version of humafiber from my PR, after that you will receive the expected behavior with timeout
Please ask questions if you have any