Răsfoiți Sursa

Tune up downloading

DarthSim 7 ani în urmă
părinte
comite
d3f93f1a9a
4 a modificat fișierele cu 27 adăugiri și 7 ștergeri
  1. 1 0
      README.md
  2. 12 5
      config.go
  3. 13 1
      download.go
  4. 1 1
      server.go

+ 1 - 0
README.md

@@ -97,6 +97,7 @@ $ xxd -g 2 -l 64 -p /dev/random | tr -d '\n'
 * `IMGPROXY_BIND` — TCP address to listen on. Default: `:8080`;
 * `IMGPROXY_READ_TIMEOUT` — the maximum duration (in seconds) for reading the entire image request, including the body. Default: `10`;
 * `IMGPROXY_WRITE_TIMEOUT` — the maximum duration (in seconds) for writing the response. Default: `10`;
+* `IMGPROXY_DOWNLOAD_TIMEOUT` — the maximum duration (in seconds) for downloading the source image. Default: `5`;
 * `IMGPROXY_CONCURRENCY` — the maximum number of image requests to be processed simultaneously. Default: `100`;
 
 #### Security

+ 12 - 5
config.go

@@ -59,11 +59,12 @@ func hexFileConfig(b *[]byte, filepath string) {
 }
 
 type config struct {
-	Bind         string
-	ReadTimeout  int
-	WriteTimeout int
-	Concurrency  int
-	TTL          int
+	Bind            string
+	ReadTimeout     int
+	WriteTimeout    int
+	DownloadTimeout int
+	Concurrency     int
+	TTL             int
 
 	MaxSrcDimension int
 
@@ -80,6 +81,7 @@ var conf = config{
 	Bind:            ":8080",
 	ReadTimeout:     10,
 	WriteTimeout:    10,
+	DownloadTimeout: 5,
 	Concurrency:     100,
 	TTL:             3600,
 	MaxSrcDimension: 4096,
@@ -95,6 +97,7 @@ func init() {
 	strEnvConfig(&conf.Bind, "IMGPROXY_BIND")
 	intEnvConfig(&conf.ReadTimeout, "IMGPROXY_READ_TIMEOUT")
 	intEnvConfig(&conf.WriteTimeout, "IMGPROXY_WRITE_TIMEOUT")
+	intEnvConfig(&conf.DownloadTimeout, "IMGPROXY_DOWNLOAD_TIMEOUT")
 	intEnvConfig(&conf.Concurrency, "IMGPROXY_CONCURRENCY")
 
 	intEnvConfig(&conf.TTL, "IMGPROXY_TTL")
@@ -131,6 +134,10 @@ func init() {
 		log.Fatalf("Write timeout should be greater than 0, now - %d\n", conf.WriteTimeout)
 	}
 
+	if conf.DownloadTimeout <= 0 {
+		log.Fatalf("Download timeout should be greater than 0, now - %d\n", conf.DownloadTimeout)
+	}
+
 	if conf.Concurrency <= 0 {
 		log.Fatalf("Concurrency should be greater than 0, now - %d\n", conf.Concurrency)
 	}

+ 13 - 1
download.go

@@ -3,15 +3,22 @@ package main
 import (
 	"bytes"
 	"errors"
+	"fmt"
 	"image"
 	"io"
+	"io/ioutil"
 	"net/http"
+	"time"
 
 	_ "image/gif"
 	_ "image/jpeg"
 	_ "image/png"
 )
 
+var downloadClient = http.Client{
+	Timeout: time.Duration(conf.DownloadTimeout) * time.Second,
+}
+
 type netReader struct {
 	reader io.Reader
 	buf    *bytes.Buffer
@@ -69,11 +76,16 @@ func readAndCheckImage(res *http.Response) ([]byte, error) {
 }
 
 func downloadImage(url string) ([]byte, error) {
-	res, err := http.Get(url)
+	res, err := downloadClient.Get(url)
 	if err != nil {
 		return nil, err
 	}
 	defer res.Body.Close()
 
+	if res.StatusCode != 200 {
+		body, _ := ioutil.ReadAll(res.Body)
+		return nil, fmt.Errorf("Can't download image; Status: %d; %s", res.StatusCode, string(body))
+	}
+
 	return readAndCheckImage(res)
 }

+ 1 - 1
server.go

@@ -174,7 +174,7 @@ func (h httpHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 
 	b, err := downloadImage(imgURL)
 	if err != nil {
-		respondWithError(rw, 404, err, "Image is unreacable")
+		respondWithError(rw, 404, err, "Image is unreachable")
 		return
 	}