0
Fork 0
mirror of https://github.com/willnorris/imageproxy.git synced 2024-12-16 21:56:43 -05:00

update allowed func to return error instead of bool

this allows returning a more accurate error message, particularly in the
case of an invalid referer header
This commit is contained in:
Will Norris 2015-12-13 16:59:56 -08:00
parent 710a2ab1c9
commit 27d53782b4
2 changed files with 17 additions and 24 deletions

View file

@ -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.

View file

@ -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)
}
}