update all downstream dependencies

no specific features I'm looking to add, just keeping thing up to date.
Unit tests and my manual testing seems like everything is still working
as expected.
This commit is contained in:
Will Norris 2017-06-01 08:37:05 -07:00
parent 17f19d612f
commit b5984d2822
25 changed files with 1661 additions and 486 deletions

View file

@ -11,8 +11,6 @@ import (
"bytes"
"errors"
"fmt"
"io"
"log"
"net/http"
"net/http/httputil"
"strings"
@ -65,23 +63,23 @@ type MemoryCache struct {
// Get returns the []byte representation of the response and true if present, false if not
func (c *MemoryCache) Get(key string) (resp []byte, ok bool) {
c.mu.RLock()
defer c.mu.RUnlock()
resp, ok = c.items[key]
c.mu.RUnlock()
return resp, ok
}
// Set saves response resp to the cache with key
func (c *MemoryCache) Set(key string, resp []byte) {
c.mu.Lock()
defer c.mu.Unlock()
c.items[key] = resp
c.mu.Unlock()
}
// Delete removes key from the cache
func (c *MemoryCache) Delete(key string) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.items, key)
c.mu.Unlock()
}
// NewMemoryCache returns a new Cache that will store items in an in-memory map
@ -90,33 +88,6 @@ func NewMemoryCache() *MemoryCache {
return c
}
// onEOFReader executes a function on reader EOF or close
type onEOFReader struct {
rc io.ReadCloser
fn func()
}
func (r *onEOFReader) Read(p []byte) (n int, err error) {
n, err = r.rc.Read(p)
if err == io.EOF {
r.runFunc()
}
return
}
func (r *onEOFReader) Close() error {
err := r.rc.Close()
r.runFunc()
return err
}
func (r *onEOFReader) runFunc() {
if fn := r.fn; fn != nil {
fn()
r.fn = nil
}
}
// Transport is an implementation of http.RoundTripper that will return values from a cache
// where possible (avoiding a network request) and will additionally add validators (etag/if-modified-since)
// to repeated requests allowing servers to return 304 / Not Modified
@ -127,10 +98,6 @@ type Transport struct {
Cache Cache
// If true, responses returned from the cache will be given an extra header, X-From-Cache
MarkCachedResponses bool
// guards modReq
mu sync.RWMutex
// Mapping of original request => cloned
modReq map[*http.Request]*http.Request
}
// NewTransport returns a new Transport with the
@ -156,20 +123,6 @@ func varyMatches(cachedResp *http.Response, req *http.Request) bool {
return true
}
// setModReq maintains a mapping between original requests and their associated cloned requests
func (t *Transport) setModReq(orig, mod *http.Request) {
t.mu.Lock()
defer t.mu.Unlock()
if t.modReq == nil {
t.modReq = make(map[*http.Request]*http.Request)
}
if mod == nil {
delete(t.modReq, orig)
} else {
t.modReq[orig] = mod
}
}
// RoundTrip takes a Request and returns a Response
//
// If there is a fresh Response already in cache, then it will be returned without connecting to
@ -180,9 +133,9 @@ func (t *Transport) setModReq(orig, mod *http.Request) {
// will be returned.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
cacheKey := cacheKey(req)
cacheableMethod := req.Method == "GET" || req.Method == "HEAD"
cacheable := (req.Method == "GET" || req.Method == "HEAD") && req.Header.Get("range") == ""
var cachedResp *http.Response
if cacheableMethod {
if cacheable {
cachedResp, err = CachedResponse(t.Cache, req)
} else {
// Need to invalidate an existing value
@ -194,7 +147,7 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error
transport = http.DefaultTransport
}
if cachedResp != nil && err == nil && cacheableMethod && req.Header.Get("range") == "" {
if cacheable && cachedResp != nil && err == nil {
if t.MarkCachedResponses {
cachedResp.Header.Set(XFromCache, "1")
}
@ -222,23 +175,7 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error
req2.Header.Set("if-modified-since", lastModified)
}
if req2 != nil {
// Associate original request with cloned request so we can refer to
// it in CancelRequest()
t.setModReq(req, req2)
req = req2
defer func() {
// Release req/clone mapping on error
if err != nil {
t.setModReq(req, nil)
}
if resp != nil {
// Release req/clone mapping on body close/EOF
resp.Body = &onEOFReader{
rc: resp.Body,
fn: func() { t.setModReq(req, nil) },
}
}
}()
}
}
}
@ -281,10 +218,7 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error
}
}
reqCacheControl := parseCacheControl(req.Header)
respCacheControl := parseCacheControl(resp.Header)
if canStore(reqCacheControl, respCacheControl) {
if cacheable && canStore(parseCacheControl(req.Header), parseCacheControl(resp.Header)) {
for _, varyKey := range headerAllCommaSepValues(resp.Header, "vary") {
varyKey = http.CanonicalHeaderKey(varyKey)
fakeHeader := "X-Varied-" + varyKey
@ -303,31 +237,6 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error
return resp, nil
}
// CancelRequest calls CancelRequest on the underlaying transport if implemented or
// throw a warning otherwise.
func (t *Transport) CancelRequest(req *http.Request) {
type canceler interface {
CancelRequest(*http.Request)
}
tr, ok := t.Transport.(canceler)
if !ok {
log.Printf("httpcache: Client Transport of type %T doesn't support CancelRequest; Timeout not supported", t.Transport)
return
}
t.mu.RLock()
if modReq, ok := t.modReq[req]; ok {
t.mu.RUnlock()
t.mu.Lock()
delete(t.modReq, req)
t.mu.Unlock()
tr.CancelRequest(modReq)
} else {
t.mu.RUnlock()
tr.CancelRequest(req)
}
}
// ErrNoDateHeader indicates that the HTTP headers contained no Date header.
var ErrNoDateHeader = errors.New("no Date header")