2021-04-26 13:52:50 +02:00
|
|
|
package router
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
2021-09-30 16:23:30 +02:00
|
|
|
"github.com/imgproxy/imgproxy/v3/ierrors"
|
|
|
|
"github.com/imgproxy/imgproxy/v3/metrics"
|
2021-04-26 13:52:50 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type timerSinceCtxKey = struct{}
|
|
|
|
|
|
|
|
func setRequestTime(r *http.Request) *http.Request {
|
|
|
|
return r.WithContext(
|
|
|
|
context.WithValue(r.Context(), timerSinceCtxKey{}, time.Now()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ctxTime(ctx context.Context) time.Duration {
|
|
|
|
if t, ok := ctx.Value(timerSinceCtxKey{}).(time.Time); ok {
|
|
|
|
return time.Since(t)
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func CheckTimeout(ctx context.Context) {
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
d := ctxTime(ctx)
|
|
|
|
|
|
|
|
if ctx.Err() != context.DeadlineExceeded {
|
|
|
|
panic(ierrors.New(499, fmt.Sprintf("Request was cancelled after %v", d), "Cancelled"))
|
|
|
|
}
|
|
|
|
|
|
|
|
metrics.SendTimeout(ctx, d)
|
|
|
|
|
|
|
|
panic(ierrors.New(503, fmt.Sprintf("Timeout after %v", d), "Timeout"))
|
|
|
|
default:
|
|
|
|
// Go ahead
|
|
|
|
}
|
|
|
|
}
|