Ejemplo n.º 1
0
        // BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue1<subdelimiter>QueryValue2
        public string CreateStorageVaryByKey(ResponseCachingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var varyByRules = context.CachedVaryByRules;

            if (varyByRules == null)
            {
                throw new InvalidOperationException($"{nameof(CachedVaryByRules)} must not be null on the {nameof(ResponseCachingContext)}");
            }

            if (StringValues.IsNullOrEmpty(varyByRules.Headers) && StringValues.IsNullOrEmpty(varyByRules.QueryKeys))
            {
                return(varyByRules.VaryByKeyPrefix);
            }

            var request = context.HttpContext.Request;
            var builder = _builderPool.Get();

            try
            {
                // Prepend with the Guid of the CachedVaryByRules
                builder.Append(varyByRules.VaryByKeyPrefix);

                // Vary by headers
                if (varyByRules?.Headers.Count > 0)
                {
                    // Append a group separator for the header segment of the cache key
                    builder.Append(KeyDelimiter)
                    .Append('H');

                    for (var i = 0; i < varyByRules.Headers.Count; i++)
                    {
                        var header       = varyByRules.Headers[i];
                        var headerValues = context.HttpContext.Request.Headers[header];
                        builder.Append(KeyDelimiter)
                        .Append(header)
                        .Append("=");

                        var headerValuesArray = headerValues.ToArray();
                        Array.Sort(headerValuesArray, StringComparer.Ordinal);

                        for (var j = 0; j < headerValuesArray.Length; j++)
                        {
                            builder.Append(headerValuesArray[j]);
                        }
                    }
                }

                // Vary by query keys
                if (varyByRules?.QueryKeys.Count > 0)
                {
                    // Append a group separator for the query key segment of the cache key
                    builder.Append(KeyDelimiter)
                    .Append('Q');

                    if (varyByRules.QueryKeys.Count == 1 && string.Equals(varyByRules.QueryKeys[0], "*", StringComparison.Ordinal))
                    {
                        // Vary by all available query keys
                        var queryArray = context.HttpContext.Request.Query.ToArray();
                        // Query keys are aggregated case-insensitively whereas the query values are compared ordinally.
                        Array.Sort(queryArray, QueryKeyComparer.OrdinalIgnoreCase);

                        for (var i = 0; i < queryArray.Length; i++)
                        {
                            builder.Append(KeyDelimiter)
                            .AppendUpperInvariant(queryArray[i].Key)
                            .Append("=");

                            var queryValueArray = queryArray[i].Value.ToArray();
                            Array.Sort(queryValueArray, StringComparer.Ordinal);

                            for (var j = 0; j < queryValueArray.Length; j++)
                            {
                                if (j > 0)
                                {
                                    builder.Append(KeySubDelimiter);
                                }

                                builder.Append(queryValueArray[j]);
                            }
                        }
                    }
                    else
                    {
                        for (var i = 0; i < varyByRules.QueryKeys.Count; i++)
                        {
                            var queryKey       = varyByRules.QueryKeys[i];
                            var queryKeyValues = context.HttpContext.Request.Query[queryKey];
                            builder.Append(KeyDelimiter)
                            .Append(queryKey)
                            .Append("=");

                            var queryValueArray = queryKeyValues.ToArray();
                            Array.Sort(queryValueArray, StringComparer.Ordinal);

                            for (var j = 0; j < queryValueArray.Length; j++)
                            {
                                if (j > 0)
                                {
                                    builder.Append(KeySubDelimiter);
                                }

                                builder.Append(queryValueArray[j]);
                            }
                        }
                    }
                }

                return(builder.ToString());
            }
            finally
            {
                _builderPool.Return(builder);
            }
        }
Ejemplo n.º 2
0
 public IEnumerable <string> CreateLookupVaryByKeys(ResponseCachingContext context)
 {
     return(new string[] { CreateStorageVaryByKey(context) });
 }