// // Implements logic as of the Request caching suitability. // // Returns: // Continue = Proceed to the next protocol stage. // DoNotTakeFromCache = Don't use cached response for this request // DoNotUseCache = Cache is not used for this request and response is not cached. public static CacheValidationStatus OnValidateRequest(HttpRequestCacheValidator ctx) { /* Some HTTP methods MUST cause a cache to invalidate an entity. This is either the entity referred to by the Request-URI, or by the Location or Content-Location headers (if present). These methods are: PUT, DELETE, POST. A cache that passes through requests for methods it does not understand SHOULD invalidate any entities referred to by the Request-URI */ if (ctx.RequestMethod >= HttpMethod.Post && ctx.RequestMethod <= HttpMethod.Delete) { if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly) { // Throw because the request must hit the wire and it's cache-only policy ctx.FailRequest(WebExceptionStatus.RequestProhibitedByCachePolicy); } // here we could return a hint on removing existing entry, but UpdateCache should handle this case correctly return CacheValidationStatus.DoNotTakeFromCache; } // // Additionally to said above we can only cache GET or HEAD, for any other methods we request bypassing cache. // if (ctx.RequestMethod < HttpMethod.Head || ctx.RequestMethod > HttpMethod.Get ) { if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly) { // Throw because the request must hit the wire and it's cache-only policy ctx.FailRequest(WebExceptionStatus.RequestProhibitedByCachePolicy); } return CacheValidationStatus.DoNotUseCache; } if (ctx.Request.Headers[HttpKnownHeaderNames.IfModifiedSince] != null || ctx.Request.Headers[HttpKnownHeaderNames.IfNoneMatch] != null || ctx.Request.Headers[HttpKnownHeaderNames.IfRange] != null || ctx.Request.Headers[HttpKnownHeaderNames.IfMatch] != null || ctx.Request.Headers[HttpKnownHeaderNames.IfUnmodifiedSince] != null ) { // The _user_ request contains conditonal cache directives // Those will conflict with the caching engine => do not lookup a cached item. if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_request_contains_conditional_header)); if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly) { // Throw because the request must hit the wire and it's cache-only policy ctx.FailRequest(WebExceptionStatus.RequestProhibitedByCachePolicy); } return CacheValidationStatus.DoNotTakeFromCache; } return CacheValidationStatus.Continue; }
public static CacheValidationStatus OnValidateRequest(HttpRequestCacheValidator ctx) { if ((ctx.RequestMethod >= HttpMethod.Post) && (ctx.RequestMethod <= HttpMethod.Delete)) { if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly) { ctx.FailRequest(WebExceptionStatus.RequestProhibitedByCachePolicy); } return CacheValidationStatus.DoNotTakeFromCache; } if ((ctx.RequestMethod < HttpMethod.Head) || (ctx.RequestMethod > HttpMethod.Get)) { if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly) { ctx.FailRequest(WebExceptionStatus.RequestProhibitedByCachePolicy); } return CacheValidationStatus.DoNotUseCache; } if (((ctx.Request.Headers["If-Modified-Since"] == null) && (ctx.Request.Headers["If-None-Match"] == null)) && (((ctx.Request.Headers["If-Range"] == null) && (ctx.Request.Headers["If-Match"] == null)) && (ctx.Request.Headers["If-Unmodified-Since"] == null))) { return CacheValidationStatus.Continue; } if (Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_request_contains_conditional_header")); } if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly) { ctx.FailRequest(WebExceptionStatus.RequestProhibitedByCachePolicy); } return CacheValidationStatus.DoNotTakeFromCache; }