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:
parent
710a2ab1c9
commit
27d53782b4
2 changed files with 17 additions and 24 deletions
|
@ -108,10 +108,9 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// assign static settings from proxy to req.Options
|
// assign static settings from proxy to req.Options
|
||||||
req.Options.ScaleUp = p.ScaleUp
|
req.Options.ScaleUp = p.ScaleUp
|
||||||
|
|
||||||
if !p.allowed(req) {
|
if err := p.allowed(req); err != nil {
|
||||||
msg := fmt.Sprintf("request does not contain an allowed host or valid signature")
|
glog.Error(err)
|
||||||
glog.Error(msg)
|
http.Error(w, err.Error(), http.StatusForbidden)
|
||||||
http.Error(w, msg, http.StatusForbidden)
|
|
||||||
return
|
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
|
// allowed determines whether the specified request contains an allowed
|
||||||
// a host in the proxy whitelist or it has a valid signature.
|
// referrer, host, and signature. It returns an error if the request is not
|
||||||
func (p *Proxy) allowed(r *Request) bool {
|
// allowed.
|
||||||
|
func (p *Proxy) allowed(r *Request) error {
|
||||||
if len(p.Referrers) > 0 && !validReferrer(p.Referrers, r.Original) {
|
if len(p.Referrers) > 0 && !validReferrer(p.Referrers, r.Original) {
|
||||||
glog.Infof("request not coming from allowed referrer: %v", r)
|
return fmt.Errorf("request does not contain an allowed referrer: %v", r)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p.Whitelist) == 0 && len(p.SignatureKey) == 0 {
|
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 len(p.Whitelist) > 0 && validHost(p.Whitelist, r.URL) {
|
||||||
if validHost(p.Whitelist, r.URL) {
|
return nil
|
||||||
return true
|
|
||||||
}
|
|
||||||
glog.Infof("request is not for an allowed host: %v", r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p.SignatureKey) > 0 {
|
if len(p.SignatureKey) > 0 && validSignature(p.SignatureKey, r) {
|
||||||
if validSignature(p.SignatureKey, r) {
|
return nil
|
||||||
return true
|
|
||||||
}
|
|
||||||
glog.Infof("request contains invalid signature: %v", r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// 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.
|
// returns whether the referrer from the request is in the host list.
|
||||||
func validReferrer(hosts []string, r *http.Request) bool {
|
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
|
if err != nil { // malformed or blank header, just deny
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return validHost(hosts, parsed)
|
return validHost(hosts, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validSignature returns whether the request signature is valid.
|
// validSignature returns whether the request signature is valid.
|
||||||
|
|
|
@ -70,7 +70,7 @@ func TestAllowed(t *testing.T) {
|
||||||
t.Errorf("error parsing url %q: %v", tt.url, err)
|
t.Errorf("error parsing url %q: %v", tt.url, err)
|
||||||
}
|
}
|
||||||
req := &Request{u, tt.options, tt.request}
|
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)
|
t.Errorf("allowed(%q) returned %v, want %v.\nTest struct: %#v", req, got, want, tt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue