1
0

timer.go 947 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package router
  2. import (
  3. "context"
  4. "net/http"
  5. "time"
  6. "github.com/imgproxy/imgproxy/v3/config"
  7. "github.com/imgproxy/imgproxy/v3/ierrors"
  8. )
  9. type timerSinceCtxKey struct{}
  10. func startRequestTimer(r *http.Request) (*http.Request, context.CancelFunc) {
  11. ctx := r.Context()
  12. ctx = context.WithValue(ctx, timerSinceCtxKey{}, time.Now())
  13. ctx, cancel := context.WithTimeout(ctx, time.Duration(config.Timeout)*time.Second)
  14. return r.WithContext(ctx), cancel
  15. }
  16. func ctxTime(ctx context.Context) time.Duration {
  17. if t, ok := ctx.Value(timerSinceCtxKey{}).(time.Time); ok {
  18. return time.Since(t)
  19. }
  20. return 0
  21. }
  22. func CheckTimeout(ctx context.Context) error {
  23. select {
  24. case <-ctx.Done():
  25. d := ctxTime(ctx)
  26. err := ctx.Err()
  27. switch err {
  28. case context.Canceled:
  29. return newRequestCancelledError(d)
  30. case context.DeadlineExceeded:
  31. return newRequestTimeoutError(d)
  32. default:
  33. return ierrors.Wrap(err, 0)
  34. }
  35. default:
  36. return nil
  37. }
  38. }