Esempio n. 1
0
        private Task <HttpResponseMessage> HandleHttpPutOrPatch(HttpRequestMessage request,
                                                                System.Threading.CancellationToken cancellationToken)
        {
            string primaryCacheKey = CacheKeyHelpers.CreatePrimaryCacheKey(request);
            var    cacheKey        = CacheKeyHelpers.CreateCacheKey(primaryCacheKey);

            // cached + conditional PUT or cached + conditional PATCH
            if ((_enableConditionalPut && request.Method == HttpMethod.Put)
                ||
                (_enableConditionalPatch && request.Method.Method.ToLower() == "patch"))
            {
                bool addCachingHeaders = false;
                HttpResponseMessage responseFromCache = null;

                // available in cache?
                var responseFromCacheAsTask = _cacheStore.GetAsync(cacheKey);
                if (responseFromCacheAsTask.Result != null)
                {
                    addCachingHeaders = true;
                    responseFromCache = responseFromCacheAsTask.Result.HttpResponse;
                }

                if (addCachingHeaders)
                {
                    // set etag / lastmodified.  Both are set for better compatibility
                    // with different backend caching systems.
                    if (responseFromCache.Headers.ETag != null)
                    {
                        request.Headers.Add(HttpHeaderConstants.IfMatch,
                                            responseFromCache.Headers.ETag.ToString());
                    }

                    if (responseFromCache.Content.Headers.LastModified != null)
                    {
                        request.Headers.Add(HttpHeaderConstants.IfUnmodifiedSince,
                                            responseFromCache.Content.Headers.LastModified.Value.ToString("r"));
                    }
                }
            }

            return(HandleSendAndContinuationForPutPatch(cacheKey, request, cancellationToken));
        }
Esempio n. 2
0
        private Task <HttpResponseMessage> HandleHttpGet(HttpRequestMessage request,
                                                         System.Threading.CancellationToken cancellationToken)
        {
            // get VaryByHeaders - order in the request shouldn't matter, so order them so the
            // rest of the logic doesn't result in different keys.


            string primaryCacheKey  = CacheKeyHelpers.CreatePrimaryCacheKey(request);// request.RequestUri.ToString();
            bool   responseIsCached = false;
            HttpResponseMessage      responseFromCache     = null;
            IEnumerable <CacheEntry> cacheEntriesFromCache = null;

            // first, before even looking at the cache:
            // The Cache-Control: no-cache HTTP/1.1 header field is also intended for use in requests made by the client.
            // It is a means for the browser to tell the server and any intermediate caches that it wants a
            // fresh version of the resource.

            if (request.Headers.CacheControl != null && request.Headers.CacheControl.NoCache)
            {
                // Don't get from cache.  Get from server.
                return(HandleSendAndContinuation(
                           CacheKeyHelpers.CreateCacheKey(primaryCacheKey), request, cancellationToken, false));
            }



            // available in cache?
            var cacheEntriesFromCacheAsTask = _cacheStore.GetAsync(primaryCacheKey);

            if (cacheEntriesFromCacheAsTask.Result != default(IEnumerable <CacheEntry>))
            {
                cacheEntriesFromCache = cacheEntriesFromCacheAsTask.Result;

                // TODO: for all of these, check the varyby headers (secondary key).
                // An item is a match if secondary & primary keys both match!
                responseFromCache = cacheEntriesFromCache.First().HttpResponse;
                responseIsCached  = true;
            }

            if (responseIsCached)
            {
                // set the accompanying request message
                responseFromCache.RequestMessage = request;

                // Check conditions that might require us to revalidate/check

                // we must assume "the worst": get from server.

                bool mustRevalidate = HttpResponseHelpers.MustRevalidate(responseFromCache);

                if (mustRevalidate)
                {
                    // we must revalidate - add headers to the request for validation.
                    //
                    // we add both ETag & IfModifiedSince for better interop with various
                    // server-side caching handlers.
                    //
                    if (responseFromCache.Headers.ETag != null)
                    {
                        request.Headers.Add(HttpHeaderConstants.IfNoneMatch,
                                            responseFromCache.Headers.ETag.ToString());
                    }

                    if (responseFromCache.Content.Headers.LastModified != null)
                    {
                        request.Headers.Add(HttpHeaderConstants.IfModifiedSince,
                                            responseFromCache.Content.Headers.LastModified.Value.ToString("r"));
                    }

                    return(HandleSendAndContinuation(
                               CacheKeyHelpers.CreateCacheKey(primaryCacheKey), request, cancellationToken, true));
                }
                else
                {
                    // response is allowed to be cached and there's
                    // no need to revalidate: return the cached response
                    return(Task.FromResult(responseFromCache));
                }
            }
            else
            {
                // response isn't cached.  Get it, and (possibly) add it to cache.
                return(HandleSendAndContinuation(
                           CacheKeyHelpers.CreateCacheKey(primaryCacheKey), request, cancellationToken, false));
            }
        }