diff --git a/imageproxy.go b/imageproxy.go index c8b5342..832fa67 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -108,10 +108,9 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { // assign static settings from proxy to req.Options req.Options.ScaleUp = p.ScaleUp - if !p.allowed(req) { - msg := fmt.Sprintf("request does not contain an allowed host or valid signature") - glog.Error(msg) - http.Error(w, msg, http.StatusForbidden) + if err := p.allowed(req); err != nil { + glog.Error(err) + http.Error(w, err.Error(), http.StatusForbidden) return } @@ -150,33 +149,27 @@ func copyHeader(w http.ResponseWriter, r *http.Response, header string) { } } -// allowed returns whether the specified request is allowed because it matches -// a host in the proxy whitelist or it has a valid signature. -func (p *Proxy) allowed(r *Request) bool { +// allowed determines whether the specified request contains an allowed +// referrer, host, and signature. It returns an error if the request is not +// allowed. +func (p *Proxy) allowed(r *Request) error { if len(p.Referrers) > 0 && !validReferrer(p.Referrers, r.Original) { - glog.Infof("request not coming from allowed referrer: %v", r) - return false + return fmt.Errorf("request does not contain an allowed referrer: %v", r) } if len(p.Whitelist) == 0 && len(p.SignatureKey) == 0 { - return true // no whitelist or signature key, all requests accepted + return nil // no whitelist or signature key, all requests accepted } - if len(p.Whitelist) > 0 { - if validHost(p.Whitelist, r.URL) { - return true - } - glog.Infof("request is not for an allowed host: %v", r) + if len(p.Whitelist) > 0 && validHost(p.Whitelist, r.URL) { + return nil } - if len(p.SignatureKey) > 0 { - if validSignature(p.SignatureKey, r) { - return true - } - glog.Infof("request contains invalid signature: %v", r) + if len(p.SignatureKey) > 0 && validSignature(p.SignatureKey, r) { + return nil } - return false + return fmt.Errorf("request does not contain an allowed host or valid signature: %v", r) } // validHost returns whether the host in u matches one of hosts. @@ -195,12 +188,12 @@ func validHost(hosts []string, u *url.URL) bool { // returns whether the referrer from the request is in the host list. func validReferrer(hosts []string, r *http.Request) bool { - parsed, err := url.Parse(r.Header.Get("Referer")) + u, err := url.Parse(r.Header.Get("Referer")) if err != nil { // malformed or blank header, just deny return false } - return validHost(hosts, parsed) + return validHost(hosts, u) } // validSignature returns whether the request signature is valid. diff --git a/imageproxy_test.go b/imageproxy_test.go index 9ddee1d..448ecfb 100644 --- a/imageproxy_test.go +++ b/imageproxy_test.go @@ -70,7 +70,7 @@ func TestAllowed(t *testing.T) { t.Errorf("error parsing url %q: %v", tt.url, err) } req := &Request{u, tt.options, tt.request} - if got, want := p.allowed(req), tt.allowed; got != want { + if got, want := p.allowed(req), tt.allowed; (got == nil) != want { t.Errorf("allowed(%q) returned %v, want %v.\nTest struct: %#v", req, got, want, tt) } }