Browse Source

Expires option (#586)

* Expires option

* Do not save expires
Svyatoslav Kryukov 4 years ago
parent
commit
098f6b9fc9
3 changed files with 47 additions and 0 deletions
  1. 11 0
      docs/generating_the_url.md
  2. 21 0
      processing_options.go
  3. 15 0
      processing_options_test.go

+ 11 - 0
docs/generating_the_url.md

@@ -480,6 +480,17 @@ It's highly recommended to prefer `cachebuster` option over URL query string bec
 
 
 Default: empty
 Default: empty
 
 
+### Expires
+
+```
+expires:%timestamp
+exp:%timestamp
+```
+
+When set, imgproxy will check provided unix timestamp and return 404 when expired.
+
+Default: empty
+
 ### Strip Metadata
 ### Strip Metadata
 
 
 ```
 ```

+ 21 - 0
processing_options.go

@@ -11,6 +11,7 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
+	"time"
 
 
 	"github.com/imgproxy/imgproxy/v2/structdiff"
 	"github.com/imgproxy/imgproxy/v2/structdiff"
 )
 )
@@ -169,6 +170,7 @@ const (
 	msgForbidden     = "Forbidden"
 	msgForbidden     = "Forbidden"
 	msgInvalidURL    = "Invalid URL"
 	msgInvalidURL    = "Invalid URL"
 	msgInvalidSource = "Invalid Source"
 	msgInvalidSource = "Invalid Source"
+	msgExpiredURL    = "Expired URL"
 )
 )
 
 
 func (gt gravityType) String() string {
 func (gt gravityType) String() string {
@@ -888,6 +890,23 @@ func applyFilenameOption(po *processingOptions, args []string) error {
 	return nil
 	return nil
 }
 }
 
 
+func applyExpiresOption(po *processingOptions, args []string) error {
+	if len(args) > 1 {
+		return fmt.Errorf("Invalid expires arguments: %v", args)
+	}
+
+	timestamp, err := strconv.ParseInt(args[0], 10, 64)
+	if err != nil {
+		return fmt.Errorf("Invalid expires argument: %v", args[0])
+	}
+
+	if timestamp > 0 && timestamp < time.Now().Unix() {
+		return errors.New(msgExpiredURL)
+	}
+
+	return nil
+}
+
 func applyStripMetadataOption(po *processingOptions, args []string) error {
 func applyStripMetadataOption(po *processingOptions, args []string) error {
 	if len(args) > 1 {
 	if len(args) > 1 {
 		return fmt.Errorf("Invalid strip metadata arguments: %v", args)
 		return fmt.Errorf("Invalid strip metadata arguments: %v", args)
@@ -972,6 +991,8 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
 		return applyAutoRotateOption(po, args)
 		return applyAutoRotateOption(po, args)
 	case "filename", "fn":
 	case "filename", "fn":
 		return applyFilenameOption(po, args)
 		return applyFilenameOption(po, args)
+	case "expires", "exp":
+		return applyExpiresOption(po, args)
 	}
 	}
 
 
 	return fmt.Errorf("Unknown processing option: %s", name)
 	return fmt.Errorf("Unknown processing option: %s", name)

+ 15 - 0
processing_options_test.go

@@ -568,6 +568,21 @@ func (s *ProcessingOptionsTestSuite) TestParsePathOnlyPresets() {
 	assert.Equal(s.T(), 50, po.Quality)
 	assert.Equal(s.T(), 50, po.Quality)
 }
 }
 
 
+func (s *ProcessingOptionsTestSuite) TestParseExpires() {
+	req := s.getRequest("/unsafe/exp:32503669200/plain/http://images.dev/lorem/ipsum.jpg")
+	_, err := parsePath(context.Background(), req)
+
+	require.Nil(s.T(), err)
+}
+
+func (s *ProcessingOptionsTestSuite) TestParseExpiresExpired() {
+	req := s.getRequest("/unsafe/exp:1609448400/plain/http://images.dev/lorem/ipsum.jpg")
+	_, err := parsePath(context.Background(), req)
+
+	require.Error(s.T(), err)
+	assert.Equal(s.T(), msgExpiredURL, err.Error())
+}
+
 func (s *ProcessingOptionsTestSuite) TestParseBase64URLOnlyPresets() {
 func (s *ProcessingOptionsTestSuite) TestParseBase64URLOnlyPresets() {
 	conf.OnlyPresets = true
 	conf.OnlyPresets = true
 	conf.Presets["test1"] = urlOptions{
 	conf.Presets["test1"] = urlOptions{