System.Net.Cache.Rfc2616.Common.ValidateCacheByVaryHeader C# (CSharp) Method

ValidateCacheByVaryHeader() static private method

static private ValidateCacheByVaryHeader ( HttpRequestCacheValidator ctx ) : TriState
ctx HttpRequestCacheValidator
return TriState
            internal static TriState ValidateCacheByVaryHeader(HttpRequestCacheValidator  ctx) {
                string[] cacheVary = ctx.CacheHeaders.GetValues(HttpKnownHeaderNames.Vary);
                if (cacheVary == null) {
                    return TriState.Unknown;
                }

                ArrayList varyValues = new ArrayList();
                HttpRequestCacheValidator.ParseHeaderValues(cacheVary,
                                                            HttpRequestCacheValidator.ParseValuesCallback,
                                                            varyValues);
                if (varyValues.Count == 0) {
                    if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_vary_header_empty));
                    return TriState.Invalid;
                }

                if (((string)(varyValues[0]))[0] == '*') {
                    if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_vary_header_contains_asterisks));
                    return TriState.Invalid;
                }

                if (ctx.SystemMeta == null || ctx.SystemMeta.Count == 0) {
                    // We keep there previous request headers
                    if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_no_headers_in_metadata));
                    return TriState.Invalid;
                }

                /*
                   A Vary field value consisting of a list of field-names signals that
                   the representation selected for the response is based on a selection
                   algorithm which considers ONLY the listed request-header field values
                   in selecting the most appropriate representation. A cache MAY assume
                   that the same selection will be made for future requests with the
                   same values for the listed field names, for the duration of time for
                   which the response is fresh.
                */

                for (int i = 0; i < varyValues.Count; ++i) {

                    string[] requestValues  = ctx.Request.Headers.GetValues((string)varyValues[i]);
                    ArrayList requestFields = new ArrayList();
                    if (requestValues != null) {
                        HttpRequestCacheValidator.ParseHeaderValues(requestValues,
                                                                    HttpRequestCacheValidator.ParseValuesCallback,
                                                                    requestFields);
                    }

                    string[] cacheValues    =  ctx.SystemMeta.GetValues((string)varyValues[i]);
                    ArrayList cacheFields = new ArrayList();
                    if (cacheValues != null) {
                        HttpRequestCacheValidator.ParseHeaderValues(cacheValues,
                                                                HttpRequestCacheValidator.ParseValuesCallback,
                                                                cacheFields);
                    }

                    if (requestFields.Count != cacheFields.Count) {
                        if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_vary_header_mismatched_count, (string)varyValues[i]));
                        return TriState.Invalid;
                    }

                    // NB: fields order is significant as per RFC.
                    for (int j = 0; j < cacheFields.Count; ++j) {
                        if (!AsciiLettersNoCaseEqual((string)cacheFields[j], (string)requestFields[j])) {
                            if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_vary_header_mismatched_field, (string)varyValues[i], (string)cacheFields[j], (string)requestFields[j]));
                            return TriState.Invalid;
                        }
                    }
                }
                if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_vary_header_match));
                // The Vary header is in cache and all headers values referenced to are equal to those in the Request.
                return TriState.Valid;
            }