소스 검색

Enable s3 transport scheme

Cyril Rohr 7 년 전
부모
커밋
7c7add8dc1
7개의 변경된 파일53개의 추가작업 그리고 18개의 파일을 삭제
  1. 1 0
      .gitignore
  2. 9 0
      README.md
  3. 5 0
      config.go
  4. 6 0
      download.go
  5. 0 7
      keepalive_old.go
  6. 32 0
      s3transport.go
  7. 0 11
      shutdown_old.go

+ 1 - 0
.gitignore

@@ -1,2 +1,3 @@
+*.swp
 imgproxy
 tmp/

+ 9 - 0
README.md

@@ -145,6 +145,7 @@ $ xxd -g 2 -l 64 -p /dev/random | tr -d '\n'
 * `IMGPROXY_MAX_CLIENTS` — the maximum number of simultaneous active connections. Default: `IMGPROXY_CONCURRENCY * 10`;
 * `IMGPROXY_TTL` — duration in seconds sent in `Expires` and `Cache-Control: max-age` headers. Default: `3600` (1 hour);
 * `IMGPROXY_USE_ETAG` — when true, enables using [ETag](https://en.wikipedia.org/wiki/HTTP_ETag) header for the cache control. Default: false;
+* `IMGPROXY_USE_S3` — when true, enables fetching the images from an `s3` source. See [Serving files from S3](#serving-files-from-s3). Default: false.
 * `IMGPROXY_LOCAL_FILESYSTEM_ROOT` — root of the local filesystem. See [Serving local files](#serving-local-files). Keep empty to disable serving of local files.
 
 #### Security
@@ -229,6 +230,14 @@ imgproxy can process files from your local filesystem. To use this feature do th
 1. Set `IMGPROXY_LOCAL_FILESYSTEM_ROOT` to your images directory path.
 2. Use `local:///path/to/image.jpg` as the source image url.
 
+## Serving files from S3
+
+imgproxy can process files from S3 buckets. To use this feature do the following:
+
+1. Set `IMGPROXY_USE_S3` to `true`.
+2. Ensure you pass `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` as environment variables. Other authentication mechanisms supported by the AWS sdk (environment, session, or instance role credentials) are also supported. The credentials need to be able to read from any of the `bucket_name` variables given in the source URLs (see below).
+3. Use `s3://%bucket_name/%object_key` as the source image url
+
 ## Source image formats support
 
 imgproxy supports only the most popular image formats of the moment: PNG, JPEG, GIF and WebP.

+ 5 - 0
config.go

@@ -99,6 +99,8 @@ type config struct {
 
 	LocalFileSystemRoot string
 
+	S3Enabled bool
+
 	ETagEnabled   bool
 	ETagSignature []byte
 
@@ -117,6 +119,7 @@ var conf = config{
 	Quality:          80,
 	GZipCompression:  5,
 	ETagEnabled:      false,
+	S3Enabled:        false,
 }
 
 func init() {
@@ -155,6 +158,8 @@ func init() {
 
 	strEnvConfig(&conf.LocalFileSystemRoot, "IMGPROXY_LOCAL_FILESYSTEM_ROOT")
 
+	boolEnvConfig(&conf.S3Enabled, "IMGPROXY_USE_S3")
+
 	boolEnvConfig(&conf.ETagEnabled, "IMGPROXY_USE_ETAG")
 
 	strEnvConfig(&conf.BaseURL, "IMGPROXY_BASE_URL")

+ 6 - 0
download.go

@@ -15,6 +15,8 @@ import (
 	_ "image/jpeg"
 	_ "image/png"
 
+	"github.com/aws/aws-sdk-go/aws/session"
+	"github.com/aws/aws-sdk-go/service/s3"
 	_ "golang.org/x/image/webp"
 )
 
@@ -62,6 +64,10 @@ func initDownloading() {
 	if conf.LocalFileSystemRoot != "" {
 		transport.RegisterProtocol("local", http.NewFileTransport(http.Dir(conf.LocalFileSystemRoot)))
 	}
+	if conf.S3Enabled {
+		svc := s3.New(session.New())
+		transport.RegisterProtocol("s3", NewS3Transport(svc))
+	}
 	downloadClient = &http.Client{
 		Timeout:   time.Duration(conf.DownloadTimeout) * time.Second,
 		Transport: transport,

+ 0 - 7
keepalive_old.go

@@ -1,7 +0,0 @@
-// +build !go1.7
-
-package main
-
-func keepAlive(i interface{}) {
-	// Dummy function. Do nothing
-}

+ 32 - 0
s3transport.go

@@ -0,0 +1,32 @@
+package main
+
+import (
+	"fmt"
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/service/s3"
+	http "net/http"
+)
+
+// s3Transport implements RoundTripper for the 's3' protocol.
+type s3Transport struct {
+	svc *s3.S3
+}
+
+func NewS3Transport(svc *s3.S3) http.RoundTripper {
+	return s3Transport{svc}
+}
+
+func (t s3Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
+	input := &s3.GetObjectInput{
+		Bucket: aws.String(req.URL.Host),
+		Key:    aws.String(req.URL.Path),
+	}
+	s3req, _ := t.svc.GetObjectRequest(input)
+
+	s3err := s3req.Send()
+	if s3err == nil { // resp is now filled
+		return s3req.HTTPResponse, nil
+	}
+	fmt.Println("s3 error", s3err)
+	return nil, s3err
+}

+ 0 - 11
shutdown_old.go

@@ -1,11 +0,0 @@
-// +build !go1.8
-
-package main
-
-import (
-	"net/http"
-)
-
-func shutdownServer(_ *http.Server) {
-	// Nothing we can do here
-}