public async Task<ValidateResult> Validate(HttpRequestBase request, HttpResponseBase response)
		{
			request.ThrowIfNull("request");
			response.ThrowIfNull("response");

			if (!String.IsNullOrEmpty(request.ContentType))
			{
				try
				{
					var contentType = new ContentType(request.ContentType);

					if (String.Equals(contentType.MediaType, "application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) || String.Equals(contentType.MediaType, "multipart/form-data", StringComparison.OrdinalIgnoreCase))
					{
						ValidationResult validationResult = await _antiCsrfNonceValidator.ValidateAsync(request);
						ResponseResult responseResult = await _antiCsrfResponseGenerator.GetResponseAsync(validationResult);

						if (responseResult.ResultType == ResponseResultType.ResponseGenerated)
						{
							return ValidateResult.ResponseGenerated(responseResult.Response);
						}
					}
				}
				catch (FormatException)
				{
				}
			}

			await _antiCsrfCookieManager.ConfigureCookieAsync(request, response);

			return ValidateResult.RequestValidated();
		}
Пример #2
0
        public bool CanMapType(HttpRequestBase request, Type parameterType)
        {
            request.ThrowIfNull("request");
            parameterType.ThrowIfNull("parameterType");

            return request.ContentType == "application/json" && _parameterTypeMatchDelegate(parameterType);
        }
        public ResponseHandlerResult HandleResponse(HttpRequestBase httpRequest, HttpResponseBase httpResponse, IResponse suggestedResponse, ICache cache, string cacheKey)
        {
            httpRequest.ThrowIfNull("httpRequest");
            httpResponse.ThrowIfNull("httpResponse");
            suggestedResponse.ThrowIfNull("suggestedResponse");

            StatusAndSubStatusCode statusCode = suggestedResponse.StatusCode;

            if (!_statusCodes.Contains(statusCode))
            {
                return ResponseHandlerResult.ResponseNotHandled();
            }

            AcceptHeader[] acceptHeaders = AcceptHeader.ParseMany(httpRequest.Headers["Accept"]).ToArray();

            if (acceptHeaders.Any() && !acceptHeaders.Any(arg => arg.MediaTypeMatches("text/plain")))
            {
                return ResponseHandlerResult.ResponseNotHandled();
            }

            Response response = new Response(statusCode)
                .TextPlain()
                .Content(String.Format("{0} {1}", statusCode.StatusDescription, statusCode.StatusDescription.Length > 0 ? String.Format("({0})", statusCode.StatusDescription) : ""));

            response.CachePolicy.NoClientCaching();

            new CacheResponse(response).WriteResponse(httpResponse);

            httpResponse.TrySkipIisCustomErrors = true;

            return ResponseHandlerResult.ResponseWritten();
        }
Пример #4
0
        public ResponseResult GetResponse(HttpRequestBase request, IEnumerable<RouteMatchResult> routeMatchResults)
        {
            request.ThrowIfNull("request");
            routeMatchResults.ThrowIfNull("routeMatchResults");

            return ResponseResult.ResponseGenerated(Response.NotFound());
        }
        public bool CanMapType(HttpRequestBase request, Type parameterType)
        {
            request.ThrowIfNull("request");
            parameterType.ThrowIfNull("parameterType");

            return parameterType.ImplementsInterface<IConvertible>();
        }
		public Cookie RenewTicket(HttpRequestBase request)
		{
			request.ThrowIfNull("request");

			HttpCookie cookie = GetRequestCookie(request);

			if (cookie == null)
			{
				return null;
			}

			FormsAuthenticationTicket ticket;

			try
			{
				ticket = System.Web.Security.FormsAuthentication.Decrypt(cookie.Value);
			}
			catch (ArgumentException)
			{
				return null;
			}

			if (ticket == null || ticket.Expired)
			{
				return null;
			}
			if (!_configuration.SlidingExpiration)
			{
				return new Cookie(cookie);
			}

			ticket = System.Web.Security.FormsAuthentication.RenewTicketIfOld(ticket);

			return ticket != null ? GenerateTicket(ticket.Expiration, ticket.UserData) : null;
		}
Пример #7
0
        public bool CanMapType(HttpRequestBase request, Type parameterType)
        {
            request.ThrowIfNull("request");
            parameterType.ThrowIfNull("parameterType");

            return true;
        }
Пример #8
0
        public bool CanMapType(HttpRequestBase request, Type parameterType)
        {
            request.ThrowIfNull("request");
            parameterType.ThrowIfNull("parameterType");

            return _parameterTypeMatchDelegate(parameterType);
        }
Пример #9
0
        public MapResult Map(HttpRequestBase request, Type type, MethodInfo method, ParameterInfo parameter)
        {
            request.ThrowIfNull("request");
            type.ThrowIfNull("type");
            method.ThrowIfNull("method");
            parameter.ThrowIfNull("parameter");

            Type parameterType = parameter.ParameterType;
            var reader = new StreamReader(request.InputStream, request.ContentEncoding);
            string json = reader.ReadToEnd();
            object jsonModel;

            try
            {
                jsonModel = JsonConvert.DeserializeObject(json, parameterType, _serializerSettings);
            }
            catch (Exception exception)
            {
                if (_errorHandling == DataConversionErrorHandling.ThrowException)
                {
                    throw new ApplicationException(String.Format("Request content could not be deserialized to '{0}'.", parameterType.FullName), exception);
                }
                jsonModel = parameterType.GetDefaultValue();
            }

            return MapResult.ValueMapped(jsonModel);
        }
Пример #10
0
        public MapResult Map(HttpRequestBase request, Type modelType, PropertyInfo property)
        {
            request.ThrowIfNull("request");
            modelType.ThrowIfNull("modelType");
            property.ThrowIfNull("property");

            return MapResult.ValueMapped(property.PropertyType.GetDefaultValue());
        }
Пример #11
0
		public Task<MapResult> MapAsync(HttpRequestBase request, Type modelType, PropertyInfo property)
		{
			request.ThrowIfNull("request");
			modelType.ThrowIfNull("modelType");
			property.ThrowIfNull("property");

			return MapResult.ValueMapped(property.PropertyType.GetDefaultValue()).AsCompletedTask();
		}
Пример #12
0
        public MapResult Map(HttpRequestBase request, Type type, MethodInfo method, ParameterInfo parameter)
        {
            request.ThrowIfNull("request");
            type.ThrowIfNull("type");
            method.ThrowIfNull("method");
            parameter.ThrowIfNull("parameter");

            return MapResult.ValueMapped(parameter.ParameterType.GetDefaultValue());
        }
Пример #13
0
        public IEnumerable<object> GetParameterValues(HttpRequestBase request, Type type, MethodInfo method)
        {
            request.ThrowIfNull("request");
            type.ThrowIfNull("type");
            method.ThrowIfNull("method");

            ParameterInfo[] parameterInfos = method.GetParameters();
            var parameterValues = new List<object>();

            foreach (ParameterInfo parameterInfo in parameterInfos)
            {
                Type parameterType = parameterInfo.ParameterType;
                string parameterName = parameterInfo.Name;
                Type currentParameterType = parameterType;

                do
                {
                    bool mapped = false;

                    foreach (IParameterMapper parameterMapper in _parameterMappers.Where(arg => arg.CanMapType(request, parameterType)))
                    {
                        MapResult mapResult = parameterMapper.Map(request, type, method, parameterInfo);

                        if (mapResult.ResultType == MapResultType.ValueNotMapped)
                        {
                            continue;
                        }

                        parameterValues.Add(mapResult.Value);
                        mapped = true;
                        break;
                    }
                    if (mapped)
                    {
                        break;
                    }

                    currentParameterType = currentParameterType.BaseType;
                } while (currentParameterType != null);

                if (currentParameterType == null)
                {
                    throw new ApplicationException(
                        String.Format(
                            "No request parameter mapper was found for parameter '{0} {1}' of '{2}.{3}'.",
                            parameterType.FullName,
                            parameterName,
                            type.FullName,
                            method.Name));
                }
            }

            return parameterValues;
        }
Пример #14
0
        public MatchResult MatchesRequest(HttpRequestBase request)
        {
            request.ThrowIfNull("request");

            MatchResult[] matchResults = _restrictions.Select(arg => arg.MatchesRequest(request)).ToArray();
            MatchResult matchingMatchResult = matchResults.FirstOrDefault(arg => arg.ResultType == MatchResultType.RestrictionMatched);

            return matchingMatchResult != null
                ? MatchResult.RestrictionMatched(matchingMatchResult.MatchedRestrictions)
                : MatchResult.RestrictionNotMatched(Enumerable.Empty<IRestriction>(), matchResults.SelectMany(arg => arg.UnmatchedRestrictions));
        }
        public ResponseHandlerResult HandleResponse(HttpRequestBase httpRequest, HttpResponseBase httpResponse, IResponse suggestedResponse, ICache cache, string cacheKey)
        {
            httpRequest.ThrowIfNull("httpRequest");
            httpResponse.ThrowIfNull("httpResponse");
            suggestedResponse.ThrowIfNull("suggestedResponse");

            var cacheResponse = new CacheResponse(suggestedResponse);

            cacheResponse.WriteResponse(httpResponse);

            return ResponseHandlerResult.ResponseWritten();
        }
        public Task ConfigureCookieAsync(HttpRequestBase request, HttpResponseBase response)
        {
            request.ThrowIfNull("request");
            response.ThrowIfNull("response");

            string cookieName = _configuration.CookieName;
            string sessionId = request.Cookies.AllKeys.Contains(cookieName) ? request.Cookies[cookieName].Value : _guidFactory.Random().ToString("N");

            response.Cookies.Remove(cookieName);

            var cookie = new HttpCookie(cookieName, sessionId) { HttpOnly = true };

            response.Cookies.Add(cookie);

            return Task.Factory.Empty();
        }
        public Task<AuthenticationResult> AuthenticateAsync(HttpRequestBase request, HttpResponseBase response, Routing.Route route)
        {
            request.ThrowIfNull("request");
            response.ThrowIfNull("response");
            route.ThrowIfNull("route");

            if (!_helper.IsTicketValid(request))
            {
                return AuthenticationResult.AuthenticationFailed.AsCompletedTask();
            }

            Cookie cookie = _helper.RenewTicket(request);

            response.Cookies.Remove(cookie.Name);
            response.Cookies.Add(cookie.GetHttpCookie());

            return AuthenticationResult.AuthenticationSucceeded.AsCompletedTask();
        }
Пример #18
0
		public Task ConfigureCookieAsync(HttpRequestBase request, HttpResponseBase response)
		{
			request.ThrowIfNull("request");
			response.ThrowIfNull("response");

			if (request.Cookies.AllKeys.Contains(_configuration.CookieName))
			{
				response.Cookies.Set(request.Cookies[_configuration.CookieName]);
				return Task.Factory.Empty();
			}

			string sessionId = _guidFactory.Random().ToString("N");
			var cookie = new HttpCookie(_configuration.CookieName, sessionId) { HttpOnly = true };

			response.Cookies.Add(cookie);

			return Task.Factory.Empty();
		}
        public ResponseHandlerResult HandleResponse(HttpRequestBase httpRequest, HttpResponseBase httpResponse, IResponse suggestedResponse, ICache cache, string cacheKey)
        {
            httpRequest.ThrowIfNull("httpRequest");
            httpResponse.ThrowIfNull("httpResponse");
            suggestedResponse.ThrowIfNull("suggestedResponse");

            StatusAndSubStatusCode statusCode = suggestedResponse.StatusCode;

            if (!_statusCodes.Contains(statusCode))
            {
                return ResponseHandlerResult.ResponseNotHandled();
            }

            AcceptHeader[] acceptHeaders = AcceptHeader.ParseMany(httpRequest.Headers["Accept"]).ToArray();

            if (acceptHeaders.Any() && !acceptHeaders.Any(arg => arg.MediaTypeMatches("text/html")))
            {
                return ResponseHandlerResult.ResponseNotHandled();
            }

            const string format = @"<!DOCTYPE html>
            <html>
            <head>
            <title>{0}</title>
            <style>h1 {{ margin: 0; padding: 0; }}</style>
            </head>
            <body>
            <h1>{0}</h1>
            <hr/>
            HTTP {1}{2}
            </body>
            </html>";
            Response response = new Response(statusCode)
                .TextHtml()
                .Content(String.Format(format, statusCode.StatusDescription, statusCode.StatusCode, statusCode.SubStatusCode == 0 ? "" : "." + statusCode.SubStatusCode));

            response.CachePolicy.NoClientCaching();

            new CacheResponse(response).WriteResponse(httpResponse);

            httpResponse.TrySkipIisCustomErrors = true;

            return ResponseHandlerResult.ResponseWritten();
        }
        public MapResult Map(HttpRequestBase request, Type type, MethodInfo method, ParameterInfo parameter)
        {
            request.ThrowIfNull("request");
            type.ThrowIfNull("type");
            method.ThrowIfNull("method");
            parameter.ThrowIfNull("parameter");

            Type parameterType = parameter.ParameterType;
            string parameterName = parameter.Name;
            string field = request.QueryString.AllKeys.LastOrDefault(arg => String.Equals(arg, parameterName, _caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase));

            if (field == null)
            {
                return MapResult.ValueNotMapped();
            }

            IConvertible value = request.QueryString[field];
            object convertedValue;

            try
            {
                convertedValue = value.ToType(parameterType, CultureInfo.InvariantCulture);
            }
            catch (Exception exception)
            {
                if (_errorHandling == DataConversionErrorHandling.ThrowException)
                {
                    throw new ApplicationException(
                        String.Format(
                            "Value for query string field '{0}' could not be converted to parameter '{1} {2}' of '{3}.{4}'.",
                            field,
                            parameterType.FullName,
                            parameterName,
                            type.FullName,
                            method.Name),
                        exception);
                }
                convertedValue = parameterType.GetDefaultValue();
            }

            return MapResult.ValueMapped(convertedValue);
        }
		public async Task<ValidationResult> ValidateAsync(HttpRequestBase request)
		{
			request.ThrowIfNull("request");

			if (!_configuration.Enabled)
			{
				return ValidationResult.ValidationDisabled;
			}
			bool isPostNeedingValidation = (String.Equals(request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase) && _configuration.ValidateHttpPost);
			bool isPutNeedingValidation = (String.Equals(request.HttpMethod, "PUT", StringComparison.OrdinalIgnoreCase) && _configuration.ValidateHttpPut);
			bool isDeleteNeedingValidation = (String.Equals(request.HttpMethod, "DELETE", StringComparison.OrdinalIgnoreCase) && _configuration.ValidateHttpDelete);

			if (!isPostNeedingValidation && !isPutNeedingValidation && !isDeleteNeedingValidation)
			{
				return ValidationResult.ValidationSkipped;
			}
			if (!request.Form.AllKeys.Contains(_configuration.FormFieldName))
			{
				return ValidationResult.FormFieldMissing;
			}
			if (!request.Cookies.AllKeys.Contains(_configuration.CookieName))
			{
				return ValidationResult.CookieMissing;
			}

			Guid nonce;

			if (!Guid.TryParse(request.Form[_configuration.FormFieldName], out nonce))
			{
				return ValidationResult.FormFieldInvalid;
			}

			HttpCookie cookie = request.Cookies[_configuration.CookieName];
			Guid sessionId;

			if (!Guid.TryParse(cookie.Value, out sessionId))
			{
				return ValidationResult.CookieInvalid;
			}

			return await _nonceRepository.ExistsAsync(sessionId, nonce, _systemClock.UtcDateTime) ? ValidationResult.NonceValid : ValidationResult.NonceInvalid;
		}
        public ResponseResult GetResponse(HttpRequestBase request, IEnumerable<RouteMatchResult> routeMatchResults)
        {
            request.ThrowIfNull("request");
            routeMatchResults.ThrowIfNull("routeMatchResults");

            routeMatchResults = routeMatchResults.ToArray();

            RouteMatchResult[] matchedResults = routeMatchResults.Where(arg => arg.MatchResult.ResultType == MatchResultType.RouteMatched).ToArray();

            if (matchedResults.Any())
            {
                int maximumMatchedRestrictions = matchedResults.Max(arg => arg.MatchResult.MatchedRestrictions.Count());
                RouteMatchResult[] bestMatches = matchedResults.Where(arg => arg.MatchResult.MatchedRestrictions.CountEqual(maximumMatchedRestrictions)).ToArray();

                if (bestMatches.Length > 1)
                {
                    return ResponseResult.ResponseGenerated(Response.MultipleChoices());
                }
                if (bestMatches.Length == 1)
                {
                    RouteMatchResult bestMatch = bestMatches[0];
                    AuthenticateResult authenticateResult = bestMatch.Route.Authenticate(request);

                    if (authenticateResult.ResultType == AuthenticateResultType.AuthenticationFailed)
                    {
                        return ResponseResult.ResponseGenerated(authenticateResult.FailedResponse ?? Response.Unauthorized());
                    }

                    IResponse response = bestMatch.Route.ProcessResponse(request);

                    if (response == null)
                    {
                        throw new ApplicationException("A matching route was found but it returned a null response.");
                    }

                    return ResponseResult.ResponseGenerated(response, bestMatch.MatchResult.CacheKey);
                }
            }

            return ResponseResult.ResponseNotGenerated();
        }
		public Task<MapResult> MapAsync(HttpRequestBase request, Type modelType, PropertyInfo property)
		{
			request.ThrowIfNull("request");
			modelType.ThrowIfNull("modelType");
			property.ThrowIfNull("property");

			Type propertyType = property.PropertyType;
			string propertyName = property.Name;
			string field = request.QueryString.AllKeys.LastOrDefault(arg => String.Equals(arg, propertyName, _caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase));

			if (field == null)
			{
				return MapResult.ValueNotMapped().AsCompletedTask();
			}

			IConvertible value = request.QueryString[field];
			object convertedValue;

			try
			{
				convertedValue = value.ToType(propertyType, CultureInfo.InvariantCulture);
			}
			catch (Exception exception)
			{
				if (_errorHandling == DataConversionErrorHandling.ThrowException)
				{
					throw new ApplicationException(
						String.Format(
							"Value of query string field '{0}' could not be converted to property '{1} {2}' of type '{3}'.",
							field,
							propertyType.FullName,
							propertyName,
							modelType.FullName),
						exception);
				}
				convertedValue = propertyType.GetDefaultValue();
			}

			return MapResult.ValueMapped(convertedValue).AsCompletedTask();
		}
        public AuthenticationResult Authenticate(HttpRequestBase request, Route route)
        {
            request.ThrowIfNull("request");
            route.ThrowIfNull("route");

            HttpCookie cookie = request.Cookies[_cookieName];

            if (cookie == null)
            {
                return AuthenticationResult.AuthenticationFailed;
            }

            try
            {
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

                return ticket.Expired ? AuthenticationResult.AuthenticationFailed : AuthenticationResult.AuthenticationSucceeded;
            }
            catch (ArgumentException)
            {
                return AuthenticationResult.AuthenticationFailed;
            }
        }
		public bool IsTicketValid(HttpRequestBase request)
		{
			request.ThrowIfNull("request");

			HttpCookie cookie = GetRequestCookie(request);

			if (cookie == null)
			{
				return false;
			}

			FormsAuthenticationTicket ticket;

			try
			{
				ticket = System.Web.Security.FormsAuthentication.Decrypt(cookie.Value);
			}
			catch (ArgumentException)
			{
				return false;
			}

			return ticket != null && !ticket.Expired;
		}
        public ResponseResult GetResponse(HttpRequestBase request, IEnumerable<RouteMatchResult> routeMatchResults)
        {
            request.ThrowIfNull("request");
            routeMatchResults.ThrowIfNull("routeMatchResults");

            RouteMatchResult[] unmatchedResults = routeMatchResults.Where(arg => arg.MatchResult.ResultType == MatchResultType.RouteNotMatched).ToArray();

            if (unmatchedResults.Any())
            {
                RouteMatchResult[] unmatchedResultsThatMatchedOnUrlRelativePath = unmatchedResults.Where(arg1 => RouteMatchedUrlRelativePath(arg1.MatchResult)).ToArray();
                int minimumUnmatchedRestrictions = unmatchedResultsThatMatchedOnUrlRelativePath.Any() ? unmatchedResultsThatMatchedOnUrlRelativePath.Min(arg => arg.MatchResult.UnmatchedRestrictions.Count()) : 0;
                RouteMatchResult[] closestMatches = unmatchedResultsThatMatchedOnUrlRelativePath.Where(arg => arg.MatchResult.UnmatchedRestrictions.Count() == minimumUnmatchedRestrictions).ToArray();

                if (closestMatches.Length == 1)
                {
                    RouteMatchResult closestMatch = closestMatches[0];
                    IRestriction[] unmatchedRestrictions = closestMatch.MatchResult.UnmatchedRestrictions.ToArray();
                    MethodRestriction[] methodRestrictions = unmatchedRestrictions.OfType<MethodRestriction>().ToArray();

                    if (methodRestrictions.Any())
                    {
                        IEnumerable<string> methods = methodRestrictions
                            .Select(arg => arg.Method)
                            .Distinct(StringComparer.OrdinalIgnoreCase)
                            .OrderBy(arg => arg);

                        return ResponseResult.ResponseGenerated(Response.MethodNotAllowed().Header("Allow", String.Join(", ", methods)));
                    }

                    IEnumerable<HeaderRestriction<AcceptHeader>> acceptHeaderRestrictions = unmatchedRestrictions.OfType<HeaderRestriction<AcceptHeader>>();

                    if (acceptHeaderRestrictions.Any())
                    {
                        return ResponseResult.ResponseGenerated(Response.NotAcceptable());
                    }

                    IEnumerable<HeaderRestriction<AcceptCharsetHeader>> acceptCharsetHeaderRestrictions = unmatchedRestrictions.OfType<HeaderRestriction<AcceptCharsetHeader>>();

                    if (acceptCharsetHeaderRestrictions.Any())
                    {
                        return ResponseResult.ResponseGenerated(Response.NotAcceptable());
                    }

                    IEnumerable<HeaderRestriction<AcceptEncodingHeader>> acceptEncodingHeaderRestrictions = unmatchedRestrictions.OfType<HeaderRestriction<AcceptEncodingHeader>>();

                    if (acceptEncodingHeaderRestrictions.Any())
                    {
                        return ResponseResult.ResponseGenerated(Response.NotAcceptable());
                    }

                    IEnumerable<HeaderRestriction<ContentEncodingHeader>> contentEncodingHeaderRestrictions = unmatchedRestrictions.OfType<HeaderRestriction<ContentEncodingHeader>>();

                    if (contentEncodingHeaderRestrictions.Any())
                    {
                        return ResponseResult.ResponseGenerated(Response.UnsupportedMediaType());
                    }
                }
            }

            return ResponseResult.ResponseNotGenerated();
        }
Пример #27
0
        public ResponseHandlerResult HandleResponse(HttpRequestBase httpRequest, HttpResponseBase httpResponse, IResponse suggestedResponse, ICache cache, string cacheKey)
        {
            httpRequest.ThrowIfNull("request");
            httpResponse.ThrowIfNull("httpResponse");
            suggestedResponse.ThrowIfNull("suggestedResponse");

            if (!suggestedResponse.CachePolicy.HasPolicy || cache == null || cacheKey == null)
            {
                return ResponseHandlerResult.ResponseNotHandled();
            }

            CacheItem cacheItem = cache.Get(cacheKey);
            string responseETag = suggestedResponse.CachePolicy.ETag;

            #region If-Match precondition header

            IfMatchHeader[] ifMatchHeaders = IfMatchHeader.ParseMany(httpRequest.Headers["If-Match"]).ToArray();

            // Only consider If-Match headers if response status code is 2xx or 412
            if (ifMatchHeaders.Any() && ((suggestedResponse.StatusCode.StatusCode >= 200 && suggestedResponse.StatusCode.StatusCode <= 299) || suggestedResponse.StatusCode.StatusCode == 412))
            {
                // Return 412 if no If-Match header matches the response ETag
                // Return 412 if an "If-Match: *" header is present and the response has no ETag
                if (ifMatchHeaders.All(arg => arg.EntityTag.Value != responseETag) ||
                    (responseETag == null && ifMatchHeaders.Any(arg => arg.EntityTag.Value == "*")))
                {
                    return WriteResponse(httpResponse, Response.PreconditionFailed());
                }
            }

            #endregion

            #region If-None-Match precondition header

            IfNoneMatchHeader[] ifNoneMatchHeaders = IfNoneMatchHeader.ParseMany(httpRequest.Headers["If-None-Match"]).ToArray();

            if (ifNoneMatchHeaders.Any())
            {
                // Return 304 if an If-None-Match header matches the response ETag and the request method was GET or HEAD
                // Return 304 if an "If-None-Match: *" header is present, the response has an ETag and the request method was GET or HEAD
                // Return 412 if an "If-None-Match: *" header is present, the response has an ETag and the request method was not GET or HEAD
                if (ifNoneMatchHeaders.Any(arg => arg.EntityTag.Value == responseETag) ||
                    (ifNoneMatchHeaders.Any(arg => arg.EntityTag.Value == "*") && responseETag != null))
                {
                    if (String.Equals(httpRequest.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase) || String.Equals(httpRequest.HttpMethod, "HEAD", StringComparison.OrdinalIgnoreCase))
                    {
                        if (cacheItem != null)
                        {
                            cacheItem.Response.CachePolicy.Apply(httpResponse.Cache);
                        }
                        else
                        {
                            suggestedResponse.CachePolicy.Apply(httpResponse.Cache);
                        }

                        return WriteResponse(httpResponse, Response.NotModified());
                    }

                    return WriteResponse(httpResponse, Response.PreconditionFailed());
                }
            }

            #endregion

            #region If-Modified-Since precondition header

            IfModifiedSinceHeader ifModifiedSinceHeader = IfModifiedSinceHeader.Parse(httpRequest.Headers["If-Modified-Since"]);
            bool validIfModifiedSinceHttpDate = ifModifiedSinceHeader != null && ifModifiedSinceHeader.HttpDate <= _systemClock.UtcDateTime;

            // Only consider an If-Modified-Since header if response status code is 200 and the HTTP-date is valid
            if (suggestedResponse.StatusCode.ParsedStatusCode == HttpStatusCode.OK && validIfModifiedSinceHttpDate)
            {
                // Return 304 if the response was cached before the HTTP-date
                if (cacheItem != null && cacheItem.CachedUtcTimestamp < ifModifiedSinceHeader.HttpDate)
                {
                    return WriteResponse(httpResponse, Response.NotModified());
                }
            }

            #endregion

            #region If-Unmodified-Since precondition header

            IfUnmodifiedSinceHeader ifUnmodifiedSinceHeader = IfUnmodifiedSinceHeader.Parse(httpRequest.Headers["If-Unmodified-Since"]);
            bool validIfUnmodifiedSinceHttpDate = ifUnmodifiedSinceHeader != null && ifUnmodifiedSinceHeader.HttpDate <= _systemClock.UtcDateTime;

            // Only consider an If-Unmodified-Since header if response status code is 2xx or 412 and the HTTP-date is valid
            if (((suggestedResponse.StatusCode.StatusCode >= 200 && suggestedResponse.StatusCode.StatusCode <= 299) || suggestedResponse.StatusCode.StatusCode == 412) && validIfUnmodifiedSinceHttpDate)
            {
                // Return 412 if the previous response was removed from the cache or was cached again at a later time
                if (cacheItem == null || cacheItem.CachedUtcTimestamp >= ifUnmodifiedSinceHeader.HttpDate)
                {
                    return WriteResponse(httpResponse, Response.PreconditionFailed());
                }
            }

            #endregion

            #region No server caching

            // Do not cache the response when the response sends a non-cacheable status code, or when an Authorization header is present
            if (!_cacheableStatusCodes.Contains(suggestedResponse.StatusCode) || httpRequest.Headers["Authorization"] != null)
            {
                return WriteResponse(httpResponse, suggestedResponse);
            }

            CacheControlHeader cacheControlHeader = CacheControlHeader.Parse(httpRequest.Headers["Cache-Control"]);

            // Do not cache the response if a "Cache-Control: no-cache" or "Cache-Control: no-store" header is present
            if (cacheControlHeader != null && (cacheControlHeader.NoCache || cacheControlHeader.NoStore))
            {
                return WriteResponse(httpResponse, suggestedResponse);
            }

            IEnumerable<PragmaHeader> pragmaHeader = PragmaHeader.ParseMany(httpRequest.Headers["Pragma"]);

            // Do not cache the response if a "Pragma: no-cache" header is present
            if (pragmaHeader.Any(arg => String.Equals(arg.Name, "no-cache", StringComparison.OrdinalIgnoreCase)))
            {
                return WriteResponse(httpResponse, suggestedResponse);
            }

            #endregion

            // Return 504 if the response has not been cached but the client is requesting to receive only a cached response
            if (cacheItem == null && cacheControlHeader != null && cacheControlHeader.OnlyIfCached)
            {
                return WriteResponse(httpResponse, Response.GatewayTimeout());
            }

            if (cacheItem != null)
            {
                // Write the cached response if no Cache-Control header is present
                // Write the cached response if a "Cache-Control: max-age" header is validated
                // Write the cached response if a "Cache-Control: max-stale" header is validated
                // Write the cached response if a "Cache-Control: min-fresh" header is validated
                if (cacheControlHeader == null ||
                    _systemClock.UtcDateTime - cacheItem.CachedUtcTimestamp <= cacheControlHeader.MaxAge ||
                    cacheControlHeader.OnlyIfCached ||
                    cacheItem.ExpiresUtcTimestamp == null ||
                    _systemClock.UtcDateTime - cacheItem.ExpiresUtcTimestamp.Value <= cacheControlHeader.MaxStale ||
                    cacheItem.ExpiresUtcTimestamp.Value - _systemClock.UtcDateTime < cacheControlHeader.MinFresh)
                {
                    return WriteResponseInCache(httpResponse, cacheItem);
                }
            }

            bool cacheOnServer = suggestedResponse.CachePolicy.AllowsServerCaching;
            var cacheResponse = new CacheResponse(suggestedResponse);

            if (cacheOnServer)
            {
                DateTime expirationUtcTimestamp = suggestedResponse.CachePolicy.ServerCacheExpirationUtcTimestamp != null
                                                      ? suggestedResponse.CachePolicy.ServerCacheExpirationUtcTimestamp.Value
                                                      : _systemClock.UtcDateTime + suggestedResponse.CachePolicy.ServerCacheMaxAge.Value;

                cache.Add(cacheKey, cacheResponse, expirationUtcTimestamp);
            }

            return WriteResponse(httpResponse, cacheResponse);
        }
        public Task<IResponse> GetFailedAuthenticationResponseAsync(HttpRequestBase request)
        {
            request.ThrowIfNull("request");

            if (_failedAuthenticationRedirectAbsoluteUrlDelegate == null)
            {
                return new Response().Unauthorized().AsCompletedTask<IResponse>();
            }

            string absoluteUrl = _failedAuthenticationRedirectAbsoluteUrlDelegate();
            Uri url;

            if (!Uri.TryCreate(absoluteUrl, UriKind.RelativeOrAbsolute, out url))
            {
                throw new InvalidOperationException("Invalid failed authentication redirect URL.");
            }

            if (_returnUrlQueryStringField != null)
            {
                string returnUrlQueryString = String.Format("{0}={1}", _returnUrlQueryStringField, HttpUtility.UrlEncode(request.RawUrl));

                absoluteUrl += (absoluteUrl.IndexOf('?') > -1 ? "&" : "?") + returnUrlQueryString;
            }

            return (String.Equals(request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase) ? new Response().Found(absoluteUrl) : new Response().SeeOther(absoluteUrl)).AsCompletedTask<IResponse>();
        }
Пример #29
0
        public MapResult Map(HttpRequestBase request, Type type, MethodInfo method, ParameterInfo parameter)
        {
            request.ThrowIfNull("request");
            type.ThrowIfNull("type");
            method.ThrowIfNull("method");
            parameter.ThrowIfNull("parameter");

            Type parameterType = parameter.ParameterType;
            object model = _container != null ? _container.GetInstance(parameterType) : Activator.CreateInstance(parameterType);
            Type modelType = model.GetType();

            foreach (PropertyInfo property in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                PropertyInfo closureProperty = property;
                var mappedValue = _modelPropertyMappers
                    .Select(arg => new { Mapper = arg, MapResult = arg.Map(request, modelType, closureProperty) })
                    .FirstOrDefault(arg => arg.MapResult.ResultType == MapResultType.ValueMapped);

                if (mappedValue == null)
                {
                    throw new ApplicationException(String.Format("Unable to map property '{0} {1}' of type '{2}'.", property.PropertyType.FullName, property.Name, modelType.FullName));
                }

                property.SetValue(model, mappedValue.MapResult.Value, null);
            }

            return MapResult.ValueMapped(model);
        }