fix(offlinegate): avoid leaking an RLock when the handler panics BE-11495 (#234)

release/2.25
andres-portainer 2024-12-11 16:38:03 -03:00 committed by GitHub
parent e1388eff84
commit 94fda6a720
2 changed files with 31 additions and 1 deletions

View File

@ -45,7 +45,9 @@ func (o *OfflineGate) WaitingMiddleware(timeout time.Duration, next http.Handler
httperror.WriteError(w, http.StatusRequestTimeout, "Request timed out while waiting for the backup process to finish", http.ErrHandlerTimeout)
return
}
defer o.lock.RUnlock()
next.ServeHTTP(w, r)
o.lock.RUnlock()
})
}

View File

@ -9,6 +9,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_canLockAndUnlock(t *testing.T) {
@ -146,3 +147,30 @@ func Test_waitingMiddleware_mayTimeout_whenLockedForTooLong(t *testing.T) {
assert.Equal(t, http.StatusRequestTimeout, response.Result().StatusCode, "Request support to timeout waiting for the gate")
}
func Test_waitingMiddleware_handlerPanics(t *testing.T) {
o := NewOfflineGate()
request := httptest.NewRequest(http.MethodPost, "/", nil)
response := httptest.NewRecorder()
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
defer func() {
recover()
wg.Done()
}()
o.WaitingMiddleware(time.Second, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
panic("panic")
})).ServeHTTP(response, request)
}()
wg.Wait()
require.True(t, o.lock.TryLock())
o.lock.Unlock()
}