From 11441a107a578672ab413fa26e883554c7b0a384 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Wed, 27 Nov 2013 12:10:29 -0800 Subject: [PATCH] add initial (pretty naive) server implementation --- imageproxy.go | 20 ++++++++++++++++++++ proxy/proxy.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 imageproxy.go diff --git a/imageproxy.go b/imageproxy.go new file mode 100644 index 0000000..39cbecd --- /dev/null +++ b/imageproxy.go @@ -0,0 +1,20 @@ +package main + +import ( + "log" + "net/http" + + "github.com/willnorris/go-imageproxy/proxy" +) + +func main() { + p := proxy.NewProxy(nil) + server := &http.Server{ + Addr: ":8080", + Handler: p, + } + err := server.ListenAndServe() + if err != nil { + log.Fatal("ListenAndServe: ", err) + } +} diff --git a/proxy/proxy.go b/proxy/proxy.go index b97ee7a..c3dfd5b 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -3,6 +3,7 @@ package proxy import ( "fmt" + "io/ioutil" "net/http" "net/url" "strconv" @@ -79,3 +80,43 @@ func NewRequest(r *http.Request) (*Request, error) { return req, nil } + +// Proxy serves image requests. +type Proxy struct { + Client *http.Client // client used to fetch remote URLs +} + +// NewProxy constructs a new proxy. The provided http Client will be used to +// fetch remote URLs. If nil is provided, http.DefaultClient will be used. +func NewProxy(client *http.Client) *Proxy { + if client == nil { + client = http.DefaultClient + } + return &Proxy{Client: client} +} + +// ServeHTTP handles image requests. +func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { + req, err := NewRequest(r) + if err != nil { + http.Error(w, fmt.Sprintf("invalid request URL: %v", err.Error()), http.StatusBadRequest) + return + } + resp, err := p.Client.Get(req.URL.String()) + if err != nil { + http.Error(w, fmt.Sprintf("error fetching remote image: %v", err.Error()), http.StatusInternalServerError) + return + } + + if resp.StatusCode != http.StatusOK { + http.Error(w, fmt.Sprintf("error fetching remote image: %v", resp.Status), resp.StatusCode) + return + } + + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + http.Error(w, fmt.Sprintf("error fetching remote image: %v", err.Error()), http.StatusInternalServerError) + } + w.Write(data) +}