📝 Description
Under heavy load, services utilizing the authentication middleware (such as BasicAuth or custom token-based auth handlers) experience connection leaks and file descriptor exhaustion. This occurs because when authentication fails, the middleware aborts the request chain early (e.g., returning a 401 Unauthorized status) but does not explicitly close or drain the incoming c.Request.Body.
While Go's net/http server attempts to automatically close the request body after the handler returns, under high concurrency and with large request payloads, the connection can hang or leak if the body is not explicitly closed or drained upon an early abort. Explicitly closing the request body on early-return ensures that the underlying TCP connection can be recycled immediately by the server.
🎯 Acceptance Criteria
🛠️ Technical Specifications & Context
The issue resides in the middleware implementation, specifically within the authentication handlers.
Key Files to Modify:
auth.go (or wherever BasicAuth / BasicAuthForRealm are defined)
Suggested Implementation:
In the authentication middleware, when credentials fail and c.AbortWithStatus(...) is called, ensure the request body is closed:
if c.Request.Body != nil {
c.Request.Body.Close()
}
Alternatively, if this is a broader issue across all early aborts, consider adding a mechanism in context.go inside the Abort or AbortWithStatus methods, or document/implement a middleware that drains and closes the body for any aborted request. However, targeting the auth middleware directly is the safest first step:
// Example in auth.go
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc {
// ... setup ...
return func(c *Context) {
// Search user/pass
if user, passwords, ok := c.Request.BasicAuth(); ok {
if password, ok := accounts[user]; ok && secureCompare(password, passwords) {
c.Set(AuthUserKey, user)
return
}
}
// Credentials failed
c.Header("WWW-Authenticate", realm)
if c.Request.Body != nil {
c.Request.Body.Close() // Explicitly close to prevent connection leaks
}
c.AbortWithStatus(http.StatusUnauthorized)
}
}
🧪 Verification & Testing
Automated Tests
- Add a test case in
auth_test.go that simulates a request with a non-empty body to an authenticated endpoint with invalid credentials.
- Verify that the request body is closed (you can wrap the
ReadCloser in a mock to assert that Close() was called).
Manual Verification under Load
- Run a test Gin server with
BasicAuth enabled.
- Use a load testing tool like
wrk or hey to send a high volume of unauthorized requests with a payload:
hey -n 10000 -c 100 -m POST -d "large_dummy_payload" http://localhost:8080/protected
- Monitor open file descriptors/connections using
lsof or netstat to ensure they do not leak or remain in CLOSE_WAIT indefinitely.

This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting /reward 100 (replace 100 with the amount).
🕵️♂️ If someone starts working on this issue to earn the rewards, they can comment /try to let everyone know!
🙌 And when they open the PR, they can comment /claim #1 either in the PR description or in a PR's comment.
🪙 Also, everyone can tip any user commenting /tip 20 @madalynerlge2 (replace 20 with the amount, and @madalynerlge2 with the user to tip).
📖 If you want to learn more, check out our documentation.
📝 Description
Under heavy load, services utilizing the authentication middleware (such as
BasicAuthor custom token-based auth handlers) experience connection leaks and file descriptor exhaustion. This occurs because when authentication fails, the middleware aborts the request chain early (e.g., returning a401 Unauthorizedstatus) but does not explicitly close or drain the incomingc.Request.Body.While Go's
net/httpserver attempts to automatically close the request body after the handler returns, under high concurrency and with large request payloads, the connection can hang or leak if the body is not explicitly closed or drained upon an early abort. Explicitly closing the request body on early-return ensures that the underlying TCP connection can be recycled immediately by the server.🎯 Acceptance Criteria
BasicAuth(),BasicAuthForRealm()) aborts the request early due to failed credentials, the request body (c.Request.Body) must be explicitly closed.c.Requestorc.Request.Bodyisnilto prevent nil-pointer dereference panics.🛠️ Technical Specifications & Context
The issue resides in the middleware implementation, specifically within the authentication handlers.
Key Files to Modify:
auth.go(or whereverBasicAuth/BasicAuthForRealmare defined)Suggested Implementation:
In the authentication middleware, when credentials fail and
c.AbortWithStatus(...)is called, ensure the request body is closed:Alternatively, if this is a broader issue across all early aborts, consider adding a mechanism in
context.goinside theAbortorAbortWithStatusmethods, or document/implement a middleware that drains and closes the body for any aborted request. However, targeting the auth middleware directly is the safest first step:🧪 Verification & Testing
Automated Tests
auth_test.gothat simulates a request with a non-empty body to an authenticated endpoint with invalid credentials.ReadCloserin a mock to assert thatClose()was called).Manual Verification under Load
BasicAuthenabled.wrkorheyto send a high volume of unauthorized requests with a payload:hey -n 10000 -c 100 -m POST -d "large_dummy_payload" http://localhost:8080/protectedlsofornetstatto ensure they do not leak or remain inCLOSE_WAITindefinitely.This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting
/reward 100(replace100with the amount).🕵️♂️ If someone starts working on this issue to earn the rewards, they can comment
/tryto let everyone know!🙌 And when they open the PR, they can comment
/claim #1either in the PR description or in a PR's comment.🪙 Also, everyone can tip any user commenting
/tip 20 @madalynerlge2(replace20with the amount, and@madalynerlge2with the user to tip).📖 If you want to learn more, check out our documentation.