From a8fb3012bdc611bdce8a77650e4949a3676602a5 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Wed, 4 Dec 2013 00:37:13 -0800 Subject: [PATCH] move data structures to data package also use io.Copy to copy fetched image to http.ResponseWriter. --- data/data.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ proxy/proxy.go | 43 +++++++++------------------------------ 2 files changed, 64 insertions(+), 34 deletions(-) create mode 100644 data/data.go diff --git a/data/data.go b/data/data.go new file mode 100644 index 0000000..a3b52f1 --- /dev/null +++ b/data/data.go @@ -0,0 +1,55 @@ +// Package data provides common shared data structures for go-imageproxy. +package data + +import ( + "errors" + "fmt" + "net/url" + "strconv" + "strings" +) + +// Transform specifies transformations that can be performed on a +// requested image. +type Transform struct { + Width int `json:"width"` // requested width, in pixels + Height int `json:"height"` // requested height, in pixels +} + +func (o Transform) String() string { + return fmt.Sprintf("%dx%d", o.Width, o.Height) +} + +func ParseTransform(str string) (*Transform, error) { + t := new(Transform) + var err error + var h, w string + + size := strings.SplitN(str, "x", 2) + w = size[0] + if len(size) > 1 { + h = size[1] + } else { + h = w + } + + if w != "" { + t.Width, err = strconv.Atoi(w) + if err != nil { + return nil, errors.New("width must be an int") + } + } + if h != "" { + t.Height, err = strconv.Atoi(h) + if err != nil { + return nil, errors.New("height must be an int") + } + } + + return t, nil +} + +type Request struct { + URL *url.URL // URL of the image to proxy + Transform *Transform // Image transformation to perform +} diff --git a/proxy/proxy.go b/proxy/proxy.go index c3dfd5b..1aace03 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -3,11 +3,12 @@ package proxy import ( "fmt" - "io/ioutil" + "io" "net/http" "net/url" - "strconv" "strings" + + "github.com/willnorris/go-imageproxy/data" ) // URLError reports a malformed URL error. @@ -20,22 +21,15 @@ func (e URLError) Error() string { return fmt.Sprintf("malformed URL %q: %s", e.URL, e.Message) } -// Request is a request for an image. -type Request struct { - URL *url.URL // URL of the image to proxy - Width int // requested width, in pixels - Height int // requested height, in pixels -} - // NewRequest parses an http.Request into an image request. -func NewRequest(r *http.Request) (*Request, error) { +func NewRequest(r *http.Request) (*data.Request, error) { path := strings.SplitN(r.URL.Path, "/", 3) if len(path) != 3 { return nil, URLError{"too few path segments", r.URL} } var err error - req := new(Request) + req := new(data.Request) req.URL, err = url.Parse(path[2]) if err != nil { @@ -55,27 +49,9 @@ func NewRequest(r *http.Request) (*Request, error) { // query string is always part of the remote URL req.URL.RawQuery = r.URL.RawQuery - - var h, w string - size := strings.SplitN(path[1], "x", 2) - w = size[0] - if len(size) > 1 { - h = size[1] - } else { - h = w - } - - if w != "" { - req.Width, err = strconv.Atoi(w) - if err != nil { - return nil, URLError{"width must be an int", r.URL} - } - } - if h != "" { - req.Height, err = strconv.Atoi(h) - if err != nil { - return nil, URLError{"height must be an int", r.URL} - } + req.Transform, err = data.ParseTransform(path[1]) + if err != nil { + return nil, URLError{err.Error(), r.URL} } return req, nil @@ -114,9 +90,8 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { } defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) + _, err = io.Copy(w, resp.Body) if err != nil { http.Error(w, fmt.Sprintf("error fetching remote image: %v", err.Error()), http.StatusInternalServerError) } - w.Write(data) }