コード例 #1
0
        /// <summary>
        /// Add a new cookie
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="options"></param>
        public static void AppendCookie(this IHeaderDictionary Headers, string key, string value, ExtendedCookieOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            bool domainHasValue  = !string.IsNullOrEmpty(options.Domain);
            bool pathHasValue    = !string.IsNullOrEmpty(options.Path);
            bool expiresHasValue = options.Expires.HasValue;
            bool maxAgeHasValue  = options.MaxAge.HasValue;

            string setCookieValue = string.Concat(
                Uri.EscapeDataString(key),
                "=",
                Uri.EscapeDataString(value ?? string.Empty),
                !domainHasValue ? null : "; domain=",
                !domainHasValue ? null : options.Domain,
                !pathHasValue ? null : "; path=",
                !pathHasValue ? null : options.Path,
                !expiresHasValue ? null : "; expires=",
                !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ", CultureInfo.InvariantCulture) + "GMT",
                !maxAgeHasValue ? null : "; max-age=",
                !maxAgeHasValue ? null : options.MaxAge.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture),
                !options.Secure ? null : "; secure",
                !options.HttpOnly ? null : "; HttpOnly");

            Headers.AppendValues("Set-Cookie", setCookieValue);
        }
コード例 #2
0
        public void AppendValues_AppendsToList()
        {
            IHeaderDictionary headers = CreateHeaders(CustomHeaderRawValues);

            headers.AppendValues(CustomHeaderKey, "vA, vB", "vC");
            IList <string> values = headers.GetValues(CustomHeaderKey);

            Assert.Equal(CustomHeaderRawValues.Concat(new[] { "vA, vB", "vC" }), values);
        }
コード例 #3
0
    public static void SetMultiValuedCookie(
        this IHeaderDictionary headers,
        string key,
        params KeyValuePair <string, string>[] values)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            throw new ArgumentNullException(nameof(key));
        }

        if (values == null)
        {
            throw new ArgumentNullException(nameof(values));
        }

        if (0 >= values.Length)
        {
            throw new ArgumentOutOfRangeException(nameof(values));
        }

        var value = string.Join("&", values.Select(v => $"{Uri.EscapeDataString(v.Key)}={Uri.EscapeDataString(v.Value)}"));

        headers.AppendValues("Set-Cookie", Uri.EscapeDataString(key) + "=" + value + "; path=/");
    }
コード例 #4
0
ファイル: ChunkingCookieManager.cs プロジェクト: rzontar/pkce
        /// <summary>
        /// Appends a new response cookie to the Set-Cookie header. If the cookie is larger than the given size limit
        /// then it will be broken down into multiple cookies as follows:
        /// Set-Cookie: CookieName=chunks:3; path=/
        /// Set-Cookie: CookieNameC1=Segment1; path=/
        /// Set-Cookie: CookieNameC2=Segment2; path=/
        /// Set-Cookie: CookieNameC3=Segment3; path=/
        /// </summary>
        /// <param name="context"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="options"></param>
        public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            bool domainHasValue   = !string.IsNullOrEmpty(options.Domain);
            bool pathHasValue     = !string.IsNullOrEmpty(options.Path);
            bool expiresHasValue  = options.Expires.HasValue;
            bool sameSiteHasValue = options.SameSite.HasValue;

            string escapedKey = Uri.EscapeDataString(key);
            string prefix     = escapedKey + "=";

            string suffix = string.Concat(
                !domainHasValue ? null : "; domain=",
                !domainHasValue ? null : options.Domain,
                !pathHasValue ? null : "; path=",
                !pathHasValue ? null : options.Path,
                !expiresHasValue ? null : "; expires=",
                !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss \\G\\M\\T", CultureInfo.InvariantCulture),
                !options.Secure ? null : "; secure",
                !options.HttpOnly ? null : "; HttpOnly",
                !sameSiteHasValue ? null : "; SameSite=",
                !sameSiteHasValue ? null : GetStringRepresentationOfSameSite(options.SameSite.Value));

            value = value ?? string.Empty;
            bool quoted = false;

            if (IsQuoted(value))
            {
                quoted = true;
                value  = RemoveQuotes(value);
            }
            string escapedValue = Uri.EscapeDataString(value);

            // Normal cookie
            IHeaderDictionary responseHeaders = context.Response.Headers;

            if (!ChunkSize.HasValue || ChunkSize.Value > prefix.Length + escapedValue.Length + suffix.Length + (quoted ? 2 : 0))
            {
                string setCookieValue = string.Concat(
                    prefix,
                    quoted ? Quote(escapedValue) : escapedValue,
                    suffix);
                responseHeaders.AppendValues(Constants.Headers.SetCookie, setCookieValue);
            }
            else if (ChunkSize.Value < prefix.Length + suffix.Length + (quoted ? 2 : 0) + 10)
            {
                // 10 is the minimum data we want to put in an individual cookie, including the cookie chunk identifier "CXX".
                // No room for data, we can't chunk the options and name
                throw new InvalidOperationException(Resources.Exception_CookieLimitTooSmall);
            }
            else
            {
                // Break the cookie down into multiple cookies.
                // Key = CookieName, value = "Segment1Segment2Segment2"
                // Set-Cookie: CookieName=chunks:3; path=/
                // Set-Cookie: CookieNameC1="Segment1"; path=/
                // Set-Cookie: CookieNameC2="Segment2"; path=/
                // Set-Cookie: CookieNameC3="Segment3"; path=/
                int dataSizePerCookie = ChunkSize.Value - prefix.Length - suffix.Length - (quoted ? 2 : 0) - 3; // Budget 3 chars for the chunkid.
                int cookieChunkCount  = (int)Math.Ceiling(escapedValue.Length * 1.0 / dataSizePerCookie);

                responseHeaders.AppendValues(Constants.Headers.SetCookie, prefix + "chunks:" + cookieChunkCount.ToString(CultureInfo.InvariantCulture) + suffix);

                string[] chunks = new string[cookieChunkCount];
                int      offset = 0;
                for (int chunkId = 1; chunkId <= cookieChunkCount; chunkId++)
                {
                    int    remainingLength = escapedValue.Length - offset;
                    int    length          = Math.Min(dataSizePerCookie, remainingLength);
                    string segment         = escapedValue.Substring(offset, length);
                    offset += length;

                    chunks[chunkId - 1] = string.Concat(
                        escapedKey,
                        "C",
                        chunkId.ToString(CultureInfo.InvariantCulture),
                        "=",
                        quoted ? "\"" : string.Empty,
                        segment,
                        quoted ? "\"" : string.Empty,
                        suffix);
                }
                responseHeaders.AppendValues(Constants.Headers.SetCookie, chunks);
            }
        }