Esempio n. 1
0
        private async Task <HttpResponseMessage> HandleRedirectRequest(string primaryCacheKey, HttpRequestMessage request, string localPath, string redirectLocation, CancellationToken cancellationToken)
        {
            var client = new HttpClient();

            try
            {
                var clonedRequest = await HttpRequestMessageExtensions.CloneHttpRequestMessageAsync(request);

                clonedRequest.RequestUri   = new Uri(redirectLocation + localPath);
                clonedRequest.Headers.Host = ConfigurationManager.AppSettings["ida:AuthorizationHost"];

                client.DefaultRequestHeaders.UserAgent.TryParseAdd(ConfigurationManager.AppSettings["userAgent"]);

                if (request.Method == HttpMethod.Get)
                {
                    clonedRequest.Content = null;
                }

                HttpResponseMessage responseMessage = await client.SendAsync(clonedRequest,
                                                                             HttpCompletionOption.ResponseHeadersRead, cancellationToken);

                // ensure no NULL dates
                if (responseMessage.Headers.Date == null)
                {
                    responseMessage.Headers.Date = DateTimeOffset.UtcNow;
                }

                // check the response: is this response allowed to be cached?
                bool isCacheable = HttpResponseHelpers.CanBeCached(responseMessage);

                if (isCacheable)
                {
                    // add the response to cache
                    memoryCache.SetHalfHour(primaryCacheKey, new CacheEntry(responseMessage));
                }

                // what about vary by headers (=> key should take this into account)?

                return(responseMessage);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                client.Dispose();
            }
        }
Esempio n. 2
0
        private async Task <HttpResponseMessage> RedirectRequest(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var localPath        = request.RequestUri.LocalPath.Replace("/proxy", "/adfs");
            var redirectLocation = ConfigurationManager.AppSettings["ida:RedirectLocation"];

            string primaryCacheKey  = request.RequestUri.ToString().ToLower();
            bool   responseIsCached = false;
            HttpResponseMessage responseFromCache = 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 && localPath != "/adfs/discovery/keys")
            {
                // Don't get from cache.  Get from server.
                return(await HandleRedirectRequest(primaryCacheKey,
                                                   request, localPath, redirectLocation, cancellationToken));
            }

            // available in cache?
            var cacheEntry = await memoryCache.GetAsync <CacheEntry>(primaryCacheKey);

            if (cacheEntry != default(CacheEntry))
            {
                // TODO: for all of these, check the varyby headers (secondary key).
                // An item is a match if secondary & primary keys both match!
                responseFromCache = new HttpResponseMessage(cacheEntry.StatusCode);
                responseFromCache.ReasonPhrase   = cacheEntry.StatusDescription;
                responseFromCache.Version        = cacheEntry.ProtocolVersion;
                responseFromCache.RequestMessage = request;

                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(Utils.Constants.HttpHeaderConstants.IfNoneMatch,
                                            responseFromCache.Headers.ETag.ToString());
                    }

                    if (responseFromCache.Content.Headers.LastModified != null)
                    {
                        request.Headers.Add(Utils.Constants.HttpHeaderConstants.IfModifiedSince,
                                            responseFromCache.Content.Headers.LastModified.Value.ToString("r"));
                    }
                    // Don't get from cache.  Get from server.
                    return(await HandleRedirectRequest(primaryCacheKey,
                                                       request, localPath, redirectLocation, cancellationToken));
                }
                else
                {
                    responseFromCache.Content = new StringContent(cacheEntry.Content, Encoding.UTF8, "application/json");

                    // response is allowed to be cached and there's
                    // no need to revalidate: return the cached response
                    return(responseFromCache);
                }
            }
            else
            {
                // Don't get from cache.  Get from server.
                return(await HandleRedirectRequest(primaryCacheKey,
                                                   request, localPath, redirectLocation, cancellationToken));
            }
        }