const stale … const fresh … const transparent … const XFromCache … type Cache … // cacheKey returns the cache key for req. func cacheKey(req *http.Request) string { … } // CachedResponse returns the cached http.Response for req if present, and nil // otherwise. func CachedResponse(c Cache, req *http.Request) (resp *http.Response, err error) { … } type MemoryCache … // 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) { … } // Set saves response resp to the cache with key func (c *MemoryCache) Set(key string, resp []byte) { … } // Delete removes key from the cache func (c *MemoryCache) Delete(key string) { … } // NewMemoryCache returns a new Cache that will store items in an in-memory map func NewMemoryCache() *MemoryCache { … } type Transport … // NewTransport returns a new Transport with the // provided Cache implementation and MarkCachedResponses set to true func NewTransport(c Cache) *Transport { … } // Client returns an *http.Client that caches responses. func (t *Transport) Client() *http.Client { … } // varyMatches will return false unless all of the cached values for the headers listed in Vary // match the new request func varyMatches(cachedResp *http.Response, req *http.Request) bool { … } // 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 // the server. // // If there is a stale Response, then any validators it contains will be set on the new request // to give the server a chance to respond with NotModified. If this happens, then the cached Response // will be returned. func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) { … } var ErrNoDateHeader … // Date parses and returns the value of the Date header. func Date(respHeaders http.Header) (date time.Time, err error) { … } type realClock … func (c *realClock) since(d time.Time) time.Duration { … } type timer … var clock … // getFreshness will return one of fresh/stale/transparent based on the cache-control // values of the request and the response // // fresh indicates the response can be returned // stale indicates that the response needs validating before it is returned // transparent indicates the response should not be used to fulfil the request // // Because this is only a private cache, 'public' and 'private' in cache-control aren't // signficant. Similarly, smax-age isn't used. func getFreshness(respHeaders, reqHeaders http.Header) (freshness int) { … } // Returns true if either the request or the response includes the stale-if-error // cache control extension: https://tools.ietf.org/html/rfc5861 func canStaleOnError(respHeaders, reqHeaders http.Header) bool { … } func getEndToEndHeaders(respHeaders http.Header) []string { … } func canStore(reqCacheControl, respCacheControl cacheControl) (canStore bool) { … } func newGatewayTimeoutResponse(req *http.Request) *http.Response { … } // cloneRequest returns a clone of the provided *http.Request. // The clone is a shallow copy of the struct and its Header map. // (This function copyright goauth2 authors: https://code.google.com/p/goauth2) func cloneRequest(r *http.Request) *http.Request { … } type cacheControl … func parseCacheControl(headers http.Header) cacheControl { … } // headerAllCommaSepValues returns all comma-separated values (each // with whitespace trimmed) for header name in headers. According to // Section 4.2 of the HTTP/1.1 spec // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2), // values from multiple occurrences of a header should be concatenated, if // the header's value is a comma-separated list. func headerAllCommaSepValues(headers http.Header, name string) []string { … } type cachingReadCloser … // Read reads the next len(p) bytes from R or until R is drained. The // return value n is the number of bytes read. If R has no data to // return, err is io.EOF and OnEOF is called with a full copy of what // has been read so far. func (r *cachingReadCloser) Read(p []byte) (n int, err error) { … } func (r *cachingReadCloser) Close() error { … } // NewMemoryCacheTransport returns a new Transport using the in-memory cache implementation func NewMemoryCacheTransport() *Transport { … }