mirror of
https://github.com/willnorris/imageproxy.git
synced 2024-12-16 21:56:43 -05:00
simplify copyHeader func
- take simple http.Header values as input, rather than http.Response - allow multiple headers to be copied to be specified. If no headers specified, then copy all.
This commit is contained in:
parent
c81621ae35
commit
a7a04ebe7b
2 changed files with 84 additions and 11 deletions
|
@ -142,27 +142,32 @@ func (p *Proxy) serveImage(w http.ResponseWriter, r *http.Request) {
|
|||
cached := resp.Header.Get(httpcache.XFromCache)
|
||||
glog.Infof("request: %v (served from cache: %v)", *req, cached == "1")
|
||||
|
||||
copyHeader(w, resp, "Cache-Control")
|
||||
copyHeader(w, resp, "Last-Modified")
|
||||
copyHeader(w, resp, "Expires")
|
||||
copyHeader(w, resp, "Etag")
|
||||
copyHeader(w, resp, "Link")
|
||||
copyHeader(w.Header(), resp.Header, "Cache-Control", "Last-Modified", "Expires", "Etag", "Link")
|
||||
|
||||
if should304(r, resp) {
|
||||
w.WriteHeader(http.StatusNotModified)
|
||||
return
|
||||
}
|
||||
|
||||
copyHeader(w, resp, "Content-Length")
|
||||
copyHeader(w, resp, "Content-Type")
|
||||
copyHeader(w.Header(), resp.Header, "Content-Length", "Content-Type")
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
func copyHeader(w http.ResponseWriter, r *http.Response, header string) {
|
||||
key := http.CanonicalHeaderKey(header)
|
||||
if value, ok := r.Header[key]; ok {
|
||||
w.Header()[key] = value
|
||||
// copyHeader copies header values from src to dst, adding to any existing
|
||||
// values with the same header name. If keys is not empty, only those header
|
||||
// keys will be copied.
|
||||
func copyHeader(dst, src http.Header, keys ...string) {
|
||||
if len(keys) == 0 {
|
||||
for k, _ := range src {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
for _, key := range keys {
|
||||
k := http.CanonicalHeaderKey(key)
|
||||
for _, v := range src[k] {
|
||||
dst.Add(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,10 +24,78 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCopyHeader(t *testing.T) {
|
||||
tests := []struct {
|
||||
dst, src http.Header
|
||||
keys []string
|
||||
want http.Header
|
||||
}{
|
||||
// empty
|
||||
{http.Header{}, http.Header{}, nil, http.Header{}},
|
||||
{http.Header{}, http.Header{}, []string{}, http.Header{}},
|
||||
{http.Header{}, http.Header{}, []string{"A"}, http.Header{}},
|
||||
|
||||
// nothing to copy
|
||||
{
|
||||
dst: http.Header{"A": []string{"a1"}},
|
||||
src: http.Header{},
|
||||
keys: nil,
|
||||
want: http.Header{"A": []string{"a1"}},
|
||||
},
|
||||
{
|
||||
dst: http.Header{},
|
||||
src: http.Header{"A": []string{"a"}},
|
||||
keys: []string{"B"},
|
||||
want: http.Header{},
|
||||
},
|
||||
|
||||
// copy headers
|
||||
{
|
||||
dst: http.Header{},
|
||||
src: http.Header{"A": []string{"a"}},
|
||||
keys: nil,
|
||||
want: http.Header{"A": []string{"a"}},
|
||||
},
|
||||
{
|
||||
dst: http.Header{"A": []string{"a"}},
|
||||
src: http.Header{"B": []string{"b"}},
|
||||
keys: nil,
|
||||
want: http.Header{"A": []string{"a"}, "B": []string{"b"}},
|
||||
},
|
||||
{
|
||||
dst: http.Header{"A": []string{"a"}},
|
||||
src: http.Header{"B": []string{"b"}, "C": []string{"c"}},
|
||||
keys: []string{"B"},
|
||||
want: http.Header{"A": []string{"a"}, "B": []string{"b"}},
|
||||
},
|
||||
{
|
||||
dst: http.Header{"A": []string{"a1"}},
|
||||
src: http.Header{"A": []string{"a2"}},
|
||||
keys: nil,
|
||||
want: http.Header{"A": []string{"a1", "a2"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
// copy dst map
|
||||
got := make(http.Header)
|
||||
for k, v := range tt.dst {
|
||||
got[k] = v
|
||||
}
|
||||
|
||||
copyHeader(got, tt.src, tt.keys...)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("copyHeader(%v, %v, %v) returned %v, want %v", tt.dst, tt.src, tt.keys, got, tt.want)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllowed(t *testing.T) {
|
||||
whitelist := []string{"good"}
|
||||
key := []byte("c0ffee")
|
||||
|
|
Loading…
Reference in a new issue