| File: ApacheModRewrite\CookieActionFactory.cs | Web Access |
| Project: src\aspnetcore\src\Middleware\Rewrite\src\Microsoft.AspNetCore.Rewrite.csproj (Microsoft.AspNetCore.Rewrite) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Globalization; using Microsoft.AspNetCore.Rewrite.UrlActions; namespace Microsoft.AspNetCore.Rewrite.ApacheModRewrite; internal sealed class CookieActionFactory { /// <summary> /// Creates a <see cref="ChangeCookieAction" /> <see href="https://httpd.apache.org/docs/current/rewrite/flags.html#flag_co" /> for details. /// </summary> /// <param name="flagValue">The flag</param> /// <returns>The action</returns> public static ChangeCookieAction Create(string flagValue) { ArgumentException.ThrowIfNullOrEmpty(flagValue); var i = 0; var separator = ':'; if (flagValue[0] == ';') { separator = ';'; i++; } ChangeCookieAction? action = null; var currentField = Fields.Name; var start = i; for (; i < flagValue.Length; i++) { if (flagValue[i] == separator) { var length = i - start; SetActionOption(flagValue.Substring(start, length).Trim(), currentField, ref action); currentField++; start = i + 1; } } if (i != start) { SetActionOption(flagValue.Substring(start).Trim(new[] { ' ', separator }), currentField, ref action); } if (currentField < Fields.Domain) { throw new FormatException(Resources.FormatError_InvalidChangeCookieFlag(flagValue)); } return action!; } private static void SetActionOption(string value, Fields tokenType, ref ChangeCookieAction? action) { Debug.Assert(action != null || tokenType == Fields.Name); switch (tokenType) { case Fields.Name: action = new ChangeCookieAction(value); break; case Fields.Value: action!.Value = value; break; case Fields.Domain: // despite what spec says, an empty domain field is allowed in mod_rewrite // by specifying NAME:VALUE:; action!.Domain = string.IsNullOrEmpty(value) || value == ";" ? null : value; break; case Fields.Lifetime: if (string.IsNullOrEmpty(value)) { break; } uint minutes; if (!uint.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out minutes)) { throw new FormatException(Resources.FormatError_CouldNotParseInteger(value)); } action!.Lifetime = TimeSpan.FromMinutes(minutes); break; case Fields.Path: action!.Path = value; break; case Fields.Secure: action!.Secure = "secure".Equals(value, StringComparison.OrdinalIgnoreCase) || "true".Equals(value, StringComparison.OrdinalIgnoreCase) || value == "1"; break; case Fields.HttpOnly: action!.HttpOnly = "httponly".Equals(value, StringComparison.OrdinalIgnoreCase) || "true".Equals(value, StringComparison.OrdinalIgnoreCase) || value == "1"; break; } } // order matters // see https://httpd.apache.org/docs/current/rewrite/flags.html#flag_co private enum Fields { Name, Value, Domain, Lifetime, Path, Secure, HttpOnly } }