Ejemplo n.º 1
0
        public void CacheHitTest()
        {
            if (Directory.Exists(Flickr.CacheLocation))
            {
                Directory.Delete(Flickr.CacheLocation, true);
            }

            Flickr f = TestData.GetInstance();

            Flickr.FlushCache();
            f.InstanceCacheDisabled = false;

            f.PeopleGetPublicPhotos(TestData.TestUserId);

            string lastUrl = f.LastRequest;

            ICacheItem item = Cache.Responses.Get(lastUrl, TimeSpan.MaxValue, false);

            Assert.IsNotNull(item, "Cache should now contain the item.");
            Assert.IsInstanceOf <ResponseCacheItem>(item);

            ResponseCacheItem response = item as ResponseCacheItem;

            Assert.IsNotNull(response.Url, "Url should not be null.");
            Assert.AreEqual(lastUrl, response.Url.AbsoluteUri, "Url should match the url requested from the cache.");
        }
Ejemplo n.º 2
0
 static void SaveResponseHeaders(HttpResponseMessage response, ResponseCacheItem itm)
 {
     foreach (var header in response.Headers)
     {
         if (!header.Key.Equals("Set-Cookie", StringComparison.OrdinalIgnoreCase) && !header.Key.Equals("cookie", StringComparison.OrdinalIgnoreCase))
         {
             itm.Headers[header.Key] = header.Value.ToArray();
         }
     }
     foreach (var header in response.Content.Headers)
     {
         itm.ContentHeaders[header.Key] = header.Value.ToArray();
     }
 }
Ejemplo n.º 3
0
            public static ResponseCacheItem ForStreamContent(HttpResponseMessage response, string storageKey)
            {
                var itm = new ResponseCacheItem
                {
                    StorageKey     = storageKey,
                    Content        = null,
                    Status         = (int)response.StatusCode,
                    Headers        = new Dictionary <string, string[]>(),
                    ContentHeaders = new Dictionary <string, string[]>(),
                    MediaType      = response.Content.Headers.ContentType.MediaType,
                    Url            = response.RequestMessage.RequestUri.ToString(),
                    Version        = response.Version
                };

                SaveResponseHeaders(response, itm);
                return(itm);
            }
Ejemplo n.º 4
0
        /// <summary>
        /// writes the content to the file system cache
        /// </summary>
        /// <param name="fileName"> the file name and path of the cache item </param>
        /// <param name="result"> the content of the cache item to be written </param>
        /// <param name="url"> the url to write the content for </param>
        private void WriteToCache(string fileName, byte[] result, Uri url)
        {
            if (!this.UseCache || string.IsNullOrEmpty(fileName))
            {
                return;
            }

            var cookieList =
                (from Cookie cookie in this.sessionCookies.GetCookies(url)
                 select new KeyValuePair(cookie.Name, cookie.Value)).ToList();

            var cacheItem = new ResponseCacheItem {
                Content = result, Cookies = cookieList
            };

            Tools.EnsurePathExist(CachePath);
            using (var file = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                new XmlSerializer(typeof(ResponseCacheItem)).Serialize(file, cacheItem);
            }
        }
Ejemplo n.º 5
0
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var requestUri       = request.RequestUri.ToString();
            var requestPath      = request.RequestUri.PathAndQuery;
            var proxyRequestHost = Context.HttpContext.Request.Host;
            var proxyAddress     = $"{Context.HttpContext.Request.Scheme}://{proxyRequestHost}";
            var siteSettings     = SiteSettings.Current;
            var sourceAddress    = siteSettings.SourceAddress;


            // Reroute access token requests
            if (IsAccessTokenRequest(requestPath))
            {
                return(new HttpResponseMessage {
                    Content = new StringContent(await HttpContext.GetTokenAsync("access_token"))
                });
            }
            if (IsIdTokenRequest(requestPath))
            {
                return(new HttpResponseMessage {
                    Content = new StringContent(await HttpContext.GetTokenAsync("id_token"))
                });
            }
            // Reroute logout
            if (IsLogoutRequest(requestPath))
            {
                return(Redirect($"{proxyAddress}/account/logout?returnUrl={WebUtility.UrlEncode(request.Headers.Referrer.ToString() ?? "/")}"));
            }

            // Reroute login request to target url (sometimes users are redirected to login if the auth cookie has only just been set)
            if (IsLoginRequest(requestPath))
            {
                var redirectUri = GetQueryParameter(request.RequestUri.Query, "redirect_to");
                if (!string.IsNullOrEmpty(redirectUri))
                {
                    return(Redirect(WebUtility.UrlDecode(redirectUri)));
                }
            }

            // Redirect to previously selected language
            if (IsRootUrl(requestPath) && siteSettings.AutoLanguageRedirect && !(request.Headers.Referrer?.ToString() ?? "").StartsWith(proxyAddress))
            {
                var requestLanguageCookie = GetRequestLanguageCookie(request);
                if (!string.IsNullOrEmpty(requestLanguageCookie) && requestLanguageCookie != siteSettings.DefaultLanguage)
                {
                    return(Redirect($"{proxyAddress}/{requestLanguageCookie}"));
                }
            }

            // Modify request headers (for authentication)
            var wpUserId = await UserService.MapToWpUserAsync(HttpContext.User);

            request.Headers.Add("X-Wp-Proxy-User-Id", wpUserId.ToString());
            request.Headers.Add("X-Wp-Proxy-Key", Settings.ProxyKey);
            request.Headers.Host = siteSettings.SourceHost;

            // Determine if content can/should be cached
            var isDynamicContent = !IsStaticContent(requestUri);
            var canCache         = CanCacheRequest(request) || !isDynamicContent;
            var isScript         = IsScript(requestUri);

            // Determine cache key
            var requestKey = canCache ? (request.RequestUri.ToString() + "|" + (isDynamicContent ? wpUserId: 0)) : null;
            var cacheKey   = canCache ? ComputeCacheKeyHash(requestKey) : null;

            // Load from cache
            if (canCache)
            {
                var responseCacheItem = await Cache.GetAsync <ResponseCacheItem>(cacheKey, refreshOnWPUpdate : isDynamicContent || isScript);

                if (responseCacheItem != null)
                {
                    var cachedResponse = await responseCacheItem.ToResponseMessage(FileStore);

                    if (canCache)
                    {
                        SetLanguageCookies(cachedResponse, request, siteSettings.DefaultLanguage);
                    }
                    return(cachedResponse);
                }
            }

            // Execute request
            if (canCache)
            {
                // Remove cookie headers
                request.Headers.Remove("cookie");
            }
            var response = await base.SendAsync(request, cancellationToken);

            if (canCache)
            {
                // Remove cookie headers
                response.Headers.Remove("cookie");
                response.Headers.Remove("set-cookie");
            }

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                return(RedirectToLogin());
            }

            // Handle depending on media type
            var mediaType = response.Content?.Headers?.ContentType?.MediaType ?? "";

            if (IsTextMediaType(mediaType))
            {
                // Text content (documents, json responses etc.) may contain references to
                // the destination/source address and the content may need to be transformed to
                // replace these references with the proxy's address

                // Read content and transform content (replace source address with proxy address)
                var contentBuilder = new StringBuilder(await response.Content.ReadAsStringAsync());
                RewriteUrls(contentBuilder, sourceAddress, proxyAddress);
                var contentString = contentBuilder.ToString();
                response.Content = new StringContent(contentString, Encoding.UTF8, response.Content.Headers.ContentType.MediaType);

                // Cache content if response is valid for caching
                if (canCache && ShouldCacheResponse(response))
                {
                    // Cache Item (if not already cached)
                    await Cache.GetOrCreateAsync(cacheKey, () => Task.FromResult(ResponseCacheItem.ForTextContent(response, contentString)), refreshOnWPUpdate : true);
                }
            }
            else if (IsMultimediaMediaType(mediaType))
            {
                // Check if response should be cached (e.g not a 500 response or similar)
                if (canCache && ShouldCacheResponse(response))
                {
                    // Read content stream to memory
                    var contentHeaders = response.Content.Headers;
                    var content        = await response.Content.ReadAsStreamAsync();

                    var ms = new MemoryStream();
                    await content.CopyToAsync(ms);

                    // Save memory stream to disk/storage cache
                    ms.Position = 0;
                    var storageKey = $"{siteSettings.SourceHost}/{cacheKey}";
                    await FileStore.WriteFileAsync(storageKey, ms);

                    // Create cache entry which references disk/storage
                    await Cache.GetOrCreateAsync(cacheKey, () => Task.FromResult(
                                                     ResponseCacheItem.ForStreamContent(response, storageKey)),
                                                 TimeSpan.FromMinutes(15),
                                                 refreshOnWPUpdate : isDynamicContent
                                                 );

                    // Link response to memory stream
                    ms.Position      = 0;
                    response.Content = new StreamContent(ms);
                    foreach (var header in contentHeaders)
                    {
                        response.Content.Headers.Add(header.Key, header.Value);
                    }
                }
            }

            RewriteRedirectUrls(response, request, sourceAddress, proxyAddress);
            if (canCache && isDynamicContent)
            {
                SetLanguageCookies(response, request, siteSettings.DefaultLanguage);
            }
            return(response);
        }