internal CookieCollection CookieCutter(Uri uri, string headerName, string setCookieHeader, bool isThrow) { CookieCollection cookies = new CookieCollection(); CookieVariant unknown = CookieVariant.Unknown; if (headerName == null) { unknown = CookieVariant.Rfc2109; } else { for (int i = 0; i < HeaderInfo.Length; i++) { if (string.Compare(headerName, HeaderInfo[i].Name, StringComparison.OrdinalIgnoreCase) == 0) { unknown = HeaderInfo[i].Variant; } } } bool isLocalDomain = this.IsLocalDomain(uri.Host); try { Cookie cookie; CookieParser parser = new CookieParser(setCookieHeader); Label_0060: cookie = parser.Get(); if (cookie != null) { if (ValidationHelper.IsBlankString(cookie.Name)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_format")); } } else if (cookie.VerifySetDefaults(unknown, uri, isLocalDomain, this.m_fqdnMyDomain, true, isThrow)) { cookies.InternalAdd(cookie, true); } goto Label_0060; } } catch (Exception exception) { if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException)) { throw; } if (isThrow) { throw new CookieException(SR.GetString("net_cookie_parse_header", new object[] { uri.AbsoluteUri }), exception); } } foreach (Cookie cookie2 in cookies) { this.Add(cookie2, isThrow); } return(cookies); }
public static bool IsRfc2965Variant(this Cookie cookie) { if (s_getVariantFunc == null) { s_getVariantFunc = (Func <Cookie, CookieVariant>) typeof(Cookie).GetProperty("Variant", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true).CreateDelegate(typeof(Func <Cookie, CookieVariant>)); } CookieVariant variant = s_getVariantFunc(cookie); return(variant == CookieVariant.Rfc2965); }
public static bool IsRfc2965Variant(this Cookie cookie) { if (s_getVariantFunc == null) { s_getVariantFunc = (Func <Cookie, CookieVariant>) typeof(Cookie).GetProperty("Variant", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true).CreateDelegate(typeof(Func <Cookie, CookieVariant>)); } Debug.Assert(s_getVariantFunc != null, "Reflection failed for Cookie.Variant."); CookieVariant variant = s_getVariantFunc(cookie); return(variant == CookieVariant.Rfc2965); }
public Cookie() { this.m_comment = string.Empty; this.m_cookieVariant = CookieVariant.Plain; this.m_domain = string.Empty; this.m_domain_implicit = true; this.m_expires = DateTime.MinValue; this.m_name = string.Empty; this.m_path = string.Empty; this.m_path_implicit = true; this.m_port = string.Empty; this.m_port_implicit = true; this.m_timeStamp = DateTime.Now; this.m_value = string.Empty; this.m_domainKey = string.Empty; }
internal CookieCollection CookieCutter(Uri uri, string headerName, string setCookieHeader, bool isThrow) { if (NetEventSource.IsEnabled) { if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"uri:{uri} headerName:{headerName} setCookieHeader:{setCookieHeader} isThrow:{isThrow}"); } } CookieCollection cookies = new CookieCollection(); CookieVariant variant = CookieVariant.Unknown; if (headerName == null) { variant = CookieVariant.Default; } else { for (int i = 0; i < s_headerInfo.Length; ++i) { if ((String.Compare(headerName, s_headerInfo[i].Name, StringComparison.OrdinalIgnoreCase) == 0)) { variant = s_headerInfo[i].Variant; } } } bool isLocalDomain = IsLocalDomain(uri.Host); try { CookieParser parser = new CookieParser(setCookieHeader); do { Cookie cookie = parser.Get(); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"CookieParser returned cookie:{cookie}"); } if (cookie == null) { break; } // Parser marks invalid cookies this way if (String.IsNullOrEmpty(cookie.Name)) { if (isThrow) { throw new CookieException(SR.net_cookie_format); } // Otherwise, ignore (reject) cookie continue; } // This will set the default values from the response URI // AND will check for cookie validity if (!cookie.VerifySetDefaults(variant, uri, isLocalDomain, m_fqdnMyDomain, true, isThrow)) { continue; } // If many same cookies arrive we collapse them into just one, hence setting // parameter isStrict = true below cookies.InternalAdd(cookie, true); } while (true); } catch (OutOfMemoryException) { throw; } catch (Exception e) { if (isThrow) { throw new CookieException(SR.Format(SR.net_cookie_parse_header, uri.AbsoluteUri), e); } } foreach (Cookie c in cookies) { Add(c, isThrow); } return(cookies); }
internal HeaderVariantInfo(string name, CookieVariant variant) { _name = name; _variant = variant; }
internal HeaderVariantInfo(string name, CookieVariant variant) { this.m_name = name; this.m_variant = variant; }
internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDomain, string localDomain, bool set_default, bool isThrow) { string host = uri.Host; int port = uri.Port; string absolutePath = uri.AbsolutePath; bool flag = true; if (set_default) { if (this.Version == 0) { variant = CookieVariant.Plain; } else if ((this.Version == 1) && (variant == CookieVariant.Unknown)) { variant = CookieVariant.Rfc2109; } this.m_cookieVariant = variant; } if (((this.m_name == null) || (this.m_name.Length == 0)) || ((this.m_name[0] == '$') || (this.m_name.IndexOfAny(Reserved2Name) != -1))) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Name", (this.m_name == null) ? "<null>" : this.m_name })); } return(false); } if ((this.m_value == null) || ((((this.m_value.Length <= 2) || (this.m_value[0] != '"')) || (this.m_value[this.m_value.Length - 1] != '"')) && (this.m_value.IndexOfAny(Reserved2Value) != -1))) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Value", (this.m_value == null) ? "<null>" : this.m_value })); } return(false); } if (((this.Comment != null) && (((this.Comment.Length <= 2) || (this.Comment[0] != '"')) || (this.Comment[this.Comment.Length - 1] != '"'))) && (this.Comment.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Comment", this.Comment })); } return(false); } if (((this.Path != null) && (((this.Path.Length <= 2) || (this.Path[0] != '"')) || (this.Path[this.Path.Length - 1] != '"'))) && (this.Path.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Path", this.Path })); } return(false); } if (set_default && this.m_domain_implicit) { this.m_domain = host; } else { if (!this.m_domain_implicit) { string domain = this.m_domain; if (!DomainCharsTest(domain)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Domain", (domain == null) ? "<null>" : domain })); } return(false); } if (domain[0] != '.') { if ((variant != CookieVariant.Rfc2965) && (variant != CookieVariant.Plain)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Domain", this.m_domain })); } return(false); } domain = '.' + domain; } int index = host.IndexOf('.'); if (isLocalDomain && (string.Compare(localDomain, domain, StringComparison.OrdinalIgnoreCase) == 0)) { flag = true; } else if (domain.IndexOf('.', 1, domain.Length - 2) == -1) { if (!IsDomainEqualToHost(domain, host)) { flag = false; } } else if (variant == CookieVariant.Plain) { if (!IsDomainEqualToHost(domain, host) && ((host.Length <= domain.Length) || (string.Compare(host, host.Length - domain.Length, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0))) { flag = false; } } else if ((((index == -1) || (domain.Length != (host.Length - index))) || (string.Compare(host, index, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0)) && !IsDomainEqualToHost(domain, host)) { flag = false; } if (flag) { this.m_domainKey = domain.ToLower(CultureInfo.InvariantCulture); } } else if (string.Compare(host, this.m_domain, StringComparison.OrdinalIgnoreCase) != 0) { flag = false; } if (!flag) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Domain", this.m_domain })); } return(false); } } if (!set_default || !this.m_path_implicit) { if (!absolutePath.StartsWith(CookieParser.CheckQuoted(this.m_path))) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Path", this.m_path })); } return(false); } } else { switch (this.m_cookieVariant) { case CookieVariant.Plain: this.m_path = absolutePath; goto Label_04F0; case CookieVariant.Rfc2109: this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/')); goto Label_04F0; } this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/') + 1); } Label_04F0: if ((set_default && !this.m_port_implicit) && (this.m_port.Length == 0)) { this.m_port_list = new int[] { port }; } if (!this.m_port_implicit) { flag = false; foreach (int num3 in this.m_port_list) { if (num3 == port) { flag = true; break; } } if (!flag) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Port", this.m_port })); } return(false); } } return(true); }
internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDomain, string localDomain, bool set_default, bool isThrow) { string host = uri.Host; int port = uri.Port; string absolutePath = uri.AbsolutePath; bool flag = true; if (set_default) { if (this.Version == 0) { variant = CookieVariant.Plain; } else if ((this.Version == 1) && (variant == CookieVariant.Unknown)) { variant = CookieVariant.Rfc2109; } this.m_cookieVariant = variant; } if (((this.m_name == null) || (this.m_name.Length == 0)) || ((this.m_name[0] == '$') || (this.m_name.IndexOfAny(Reserved2Name) != -1))) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Name", (this.m_name == null) ? "<null>" : this.m_name })); } return false; } if ((this.m_value == null) || ((((this.m_value.Length <= 2) || (this.m_value[0] != '"')) || (this.m_value[this.m_value.Length - 1] != '"')) && (this.m_value.IndexOfAny(Reserved2Value) != -1))) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Value", (this.m_value == null) ? "<null>" : this.m_value })); } return false; } if (((this.Comment != null) && (((this.Comment.Length <= 2) || (this.Comment[0] != '"')) || (this.Comment[this.Comment.Length - 1] != '"'))) && (this.Comment.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Comment", this.Comment })); } return false; } if (((this.Path != null) && (((this.Path.Length <= 2) || (this.Path[0] != '"')) || (this.Path[this.Path.Length - 1] != '"'))) && (this.Path.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Path", this.Path })); } return false; } if (set_default && this.m_domain_implicit) { this.m_domain = host; } else { if (!this.m_domain_implicit) { string domain = this.m_domain; if (!DomainCharsTest(domain)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Domain", (domain == null) ? "<null>" : domain })); } return false; } if (domain[0] != '.') { if ((variant != CookieVariant.Rfc2965) && (variant != CookieVariant.Plain)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Domain", this.m_domain })); } return false; } domain = '.' + domain; } int index = host.IndexOf('.'); if (isLocalDomain && (string.Compare(localDomain, domain, StringComparison.OrdinalIgnoreCase) == 0)) { flag = true; } else if (domain.IndexOf('.', 1, domain.Length - 2) == -1) { if (!IsDomainEqualToHost(domain, host)) { flag = false; } } else if (variant == CookieVariant.Plain) { if (!IsDomainEqualToHost(domain, host) && ((host.Length <= domain.Length) || (string.Compare(host, host.Length - domain.Length, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0))) { flag = false; } } else if ((((index == -1) || (domain.Length != (host.Length - index))) || (string.Compare(host, index, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0)) && !IsDomainEqualToHost(domain, host)) { flag = false; } if (flag) { this.m_domainKey = domain.ToLower(CultureInfo.InvariantCulture); } } else if (string.Compare(host, this.m_domain, StringComparison.OrdinalIgnoreCase) != 0) { flag = false; } if (!flag) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Domain", this.m_domain })); } return false; } } if (!set_default || !this.m_path_implicit) { if (!absolutePath.StartsWith(CookieParser.CheckQuoted(this.m_path))) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Path", this.m_path })); } return false; } } else { switch (this.m_cookieVariant) { case CookieVariant.Plain: this.m_path = absolutePath; goto Label_04F0; case CookieVariant.Rfc2109: this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/')); goto Label_04F0; } this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/') + 1); } Label_04F0: if ((set_default && !this.m_port_implicit) && (this.m_port.Length == 0)) { this.m_port_list = new int[] { port }; } if (!this.m_port_implicit) { flag = false; foreach (int num3 in this.m_port_list) { if (num3 == port) { flag = true; break; } } if (!flag) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_attribute", new object[] { "Port", this.m_port })); } return false; } } return true; }
internal CookieCollection CookieCutter(Uri uri, string HeaderName, string setCookieHeader, bool isThrow) { CookieCollection cookies = new CookieCollection(); CookieVariant variant = CookieVariant.Unknown; if (HeaderName == null) { variant = CookieVariant.Default; } else { for (int i = 0; i < HeaderInfo.Length; ++i) { if ((String.Compare(HeaderName, HeaderInfo[i].Name, true, CultureInfo.InvariantCulture) == 0)) { variant = HeaderInfo[i].Variant; } } } bool isLocalDomain = IsLocal(uri.Host); try { CookieParser parser = new CookieParser(setCookieHeader); do { Cookie cookie = parser.Get(); if (cookie == null) { //Console.WriteLine("CookieCutter: eof cookies"); break; } //Parser marks invalid cookies this way if (cookie.Name == string.Empty) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_format)); } //Otherwise, ignore (reject) cookie continue; } // this will set the default values from the response URI // AND will check for cookie validity if (!cookie.VerifySetDefaults(variant, uri, isLocalDomain, m_fqdnMyDomain, true, isThrow)) { continue; } // If many same cookies arrive we collapse them into just one, hence setting // parameter isStrict = true below cookies.InternalAdd(cookie, true); } while (true); } catch (Exception e) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_parse_header, uri.AbsoluteUri), e); } } foreach (Cookie c in cookies) { Add(c, isThrow); } return(cookies); }
// According to spec we must assume default values for attributes but still // keep in mind that we must not include them into the requests. // We also check the validity of all attributes based on the version and variant (read RFC) // // To work properly this function must be called after cookie construction with // default (response) URI AND setDefault == true // // Afterwards, the function can be called many times with other URIs and // setDefault == false to check whether this cookie matches given uri internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDomain, string localDomain, bool setDefault, bool shouldThrow) { string host = uri.Host; int port = uri.Port; string path = uri.AbsolutePath; bool valid = true; if (setDefault) { // Set Variant. If version is zero => reset cookie to Version0 style if (Version == 0) { variant = CookieVariant.Plain; } else if (Version == 1 && variant == CookieVariant.Unknown) { // Since we don't expose Variant to an app, set it to Default variant = CookieVariant.Default; } m_cookieVariant = variant; } // Check the name if (string.IsNullOrEmpty(m_name) || m_name.StartsWith('$') || m_name.StartsWith(' ') || m_name.EndsWith(' ') || m_name.AsSpan().IndexOfAny(ReservedToName) >= 0) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, "Name", m_name ?? "<null>")); } return(false); } // Check the value if (m_value == null || (!(m_value.Length > 2 && m_value.StartsWith('\"') && m_value.EndsWith('\"')) && m_value.AsSpan().IndexOfAny(';', ',') >= 0)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, "Value", m_value ?? "<null>")); } return(false); } // Check Comment syntax if (Comment != null && !(Comment.Length > 2 && Comment.StartsWith('\"') && Comment.EndsWith('\"')) && (Comment.AsSpan().IndexOfAny(';', ',') >= 0)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.CommentAttributeName, Comment)); } return(false); } // Check Path syntax if (Path != null && !(Path.Length > 2 && Path.StartsWith('\"') && Path.EndsWith('\"')) && (Path.AsSpan().IndexOfAny(';', ',') != -1)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.PathAttributeName, Path)); } return(false); } // Check/set domain // // If domain is implicit => assume a) uri is valid, b) just set domain to uri hostname. if (setDefault && m_domain_implicit) { m_domain = host; } else { if (!m_domain_implicit) { // Forwarding note: If Uri.Host is of IP address form then the only supported case // is for IMPLICIT domain property of a cookie. // The code below (explicit cookie.Domain value) will try to parse Uri.Host IP string // as a fqdn and reject the cookie. // Aliasing since we might need the KeyValue (but not the original one). string domain = m_domain; // Syntax check for Domain charset plus empty string. if (!DomainCharsTest(domain)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, domain ?? "<null>")); } return(false); } // Domain must start with '.' if set explicitly. if (domain[0] != '.') { domain = '.' + domain; } int host_dot = host.IndexOf('.'); // First quick check is for pushing a cookie into the local domain. if (isLocalDomain && string.Equals(localDomain, domain, StringComparison.OrdinalIgnoreCase)) { valid = true; } else if (domain.IndexOf('.', 1, domain.Length - 2) == -1) { // A single label domain is valid only if the domain is exactly the same as the host specified in the URI. if (!IsDomainEqualToHost(domain, host)) { valid = false; } } else if (variant == CookieVariant.Plain) { // We distinguish between Version0 cookie and other versions on domain issue. // According to Version0 spec a domain must be just a substring of the hostname. if (!IsDomainEqualToHost(domain, host)) { if (host.Length <= domain.Length || (string.Compare(host, host.Length - domain.Length, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0)) { valid = false; } } } else if (host_dot == -1 || domain.Length != host.Length - host_dot || (string.Compare(host, host_dot, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0)) { // Starting from the first dot, the host must match the domain. // // For null hosts, the host must match the domain exactly. if (!IsDomainEqualToHost(domain, host)) { valid = false; } } if (valid) { m_domainKey = domain.ToLowerInvariant(); } } else { // For implicitly set domain AND at the set_default == false time // we simply need to match uri.Host against m_domain. if (!string.Equals(host, m_domain, StringComparison.OrdinalIgnoreCase)) { valid = false; } } if (!valid) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, m_domain)); } return(false); } } // Check/Set Path if (setDefault && m_path_implicit) { // This code assumes that the URI path is always valid and contains at least one '/'. switch (m_cookieVariant) { case CookieVariant.Plain: // As per RFC6265 5.1.4. (https://tools.ietf.org/html/rfc6265#section-5.1.4): // | 2. If the uri-path is empty or if the first character of the uri- // | path is not a %x2F ("/") character, output %x2F ("/") and skip // | the remaining steps. // | 3. If the uri-path contains no more than one %x2F ("/") character, // | output %x2F ("/") and skip the remaining step. // Note: Normally Uri.AbsolutePath contains at least one "/" after parsing, // but it's possible construct Uri with an empty path using a custom UriParser int lastSlash; if (!path.StartsWith('/') || (lastSlash = path.LastIndexOf('/')) == 0) { m_path = "/"; break; } // | 4. Output the characters of the uri-path from the first character up // | to, but not including, the right-most %x2F ("/"). m_path = path.Substring(0, lastSlash); break; case CookieVariant.Rfc2109: m_path = path.Substring(0, path.LastIndexOf('/')); // May be empty break; case CookieVariant.Rfc2965: default: // NOTE: this code is not resilient against future versions with different 'Path' semantics. m_path = path.Substring(0, path.LastIndexOf('/') + 1); break; } } // Set the default port if Port attribute was present but had no value. if (setDefault && (m_port_implicit == false && m_port.Length == 0)) { m_port_list = new int[1] { port }; } if (m_port_implicit == false) { // Port must match against the one from the uri. valid = false; foreach (int p in m_port_list !) { if (p == port) { valid = true; break; } } if (!valid) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.PortAttributeName, m_port)); } return(false); } } return(true); }
internal CookieCollection CookieCutter(Uri uri, string headerName, string setCookieHeader, bool isThrow) { GlobalLog.Print("CookieContainer#" + ValidationHelper.HashString(this) + "::CookieCutter() uri:" + uri + " headerName:" + headerName + " setCookieHeader:" + setCookieHeader + " isThrow:" + isThrow); CookieCollection cookies = new CookieCollection(); CookieVariant variant = CookieVariant.Unknown; if (headerName == null) { variant = CookieVariant.Default; } else { for (int i = 0; i < HeaderInfo.Length; ++i) { if ((String.Compare(headerName, HeaderInfo[i].Name, StringComparison.OrdinalIgnoreCase) == 0)) { variant = HeaderInfo[i].Variant; } } } bool isLocalDomain = IsLocalDomain(uri.Host); try { CookieParser parser = new CookieParser(setCookieHeader); do { Cookie cookie = parser.Get(); GlobalLog.Print("CookieContainer#" + ValidationHelper.HashString(this) + "::CookieCutter() CookieParser returned cookie:" + ValidationHelper.ToString(cookie)); if (cookie == null) { break; } //Parser marks invalid cookies this way if (ValidationHelper.IsBlankString(cookie.Name)) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_format)); } //Otherwise, ignore (reject) cookie continue; } // this will set the default values from the response URI // AND will check for cookie validity if (!cookie.VerifySetDefaults(variant, uri, isLocalDomain, m_fqdnMyDomain, true, isThrow)) { continue; } // If many same cookies arrive we collapse them into just one, hence setting // parameter isStrict = true below cookies.InternalAdd(cookie, true); } while (true); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_parse_header, uri.AbsoluteUri), e); } } foreach (Cookie c in cookies) { Add(c, isThrow); } return(cookies); }
// // According to spec we must assume default values for attributes but still // keep in mind that we must not include them into the requests. // We also check the validiy of all attributes based on the version and variant (read RFC) // // To work properly this function must be called after cookie construction with // default (response) URI AND set_default == true // // Afterwards, the function can be called many times with other URIs and // set_default == false to check whether this cookie matches given uri // internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDomain, string localDomain, bool set_default, bool isThrow) { string host = uri.Host; int port = uri.Port; string path = uri.AbsolutePath; bool valid= true; if (set_default) { // Set Variant. If version is zero => reset cookie to Version0 style if (Version == 0) { variant = CookieVariant.Plain; } else if (Version == 1 && variant == CookieVariant.Unknown) { //since we don't expose Variant to an app, set it to Default variant = CookieVariant.Default; } m_cookieVariant = variant; } //Check the name if (m_name == null || m_name.Length == 0 || m_name[0] == '$' || m_name.IndexOfAny(Reserved2Name) != -1) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, "Name", m_name == null? "<null>": m_name)); } return false; } //Check the value if (m_value == null || (!(m_value.Length > 2 && m_value[0] == '\"' && m_value[m_value.Length-1] == '\"') && m_value.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, "Value", m_value == null? "<null>": m_value)); } return false; } //Check Comment syntax if (Comment != null && !(Comment.Length > 2 && Comment[0] == '\"' && Comment[Comment.Length-1] == '\"') && (Comment.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) throw new CookieException(SR.GetString(SR.net_cookie_attribute, CommentAttributeName, Comment)); return false; } //Check Path syntax if (Path != null && !(Path.Length > 2 && Path[0] == '\"' && Path[Path.Length-1] == '\"') && (Path.IndexOfAny(Reserved2Value) != -1)) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, PathAttributeName, Path)); } return false; } //Check/set domain // if domain is implicit => assume a) uri is valid, b) just set domain to uri hostname if (set_default && m_domain_implicit == true) { m_domain = host; } else { if (!m_domain_implicit) { // Forwarding note: If Uri.Host is of IP address form then the only supported case // is for IMPLICIT domain property of a cookie. // The below code (explicit cookie.Domain value) will try to parse Uri.Host IP string // as a fqdn and reject the cookie //aliasing since we might need the KeyValue (but not the original one) string domain = m_domain; //Syntax check for Domain charset plus empty string if (!DomainCharsTest(domain)) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, DomainAttributeName, domain == null? "<null>": domain)); } return false; } //domain must start with '.' if set explicitly if(domain[0] != '.' ) { if (!(variant == CookieVariant.Rfc2965 || variant == CookieVariant.Plain)) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, DomainAttributeName, m_domain)); } return false; } domain = '.' + domain; } int host_dot = host.IndexOf('.'); // First quick check is for pushing a cookie into the local domain if (isLocalDomain && (string.Compare(localDomain, domain, StringComparison.OrdinalIgnoreCase ) == 0)) { valid = true; } else if (domain.IndexOf('.', 1, domain.Length-2) == -1) { // A single label domain is valid only if the domain is exactly the same as the host specified in the URI if (!IsDomainEqualToHost(domain, host)) { valid = false; } } else if (variant == CookieVariant.Plain) { // We distiguish between Version0 cookie and other versions on domain issue // According to Version0 spec a domain must be just a substring of the hostname if (!IsDomainEqualToHost(domain, host)) { if (host.Length <= domain.Length || string.Compare(host, host.Length-domain.Length, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0) { valid = false; } } } else if (host_dot == -1 || domain.Length != host.Length-host_dot || string.Compare(host, host_dot, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0) { //starting the first dot, the host must match the domain // for null hosts, the host must match the domain exactly if (!IsDomainEqualToHost(domain, host)) { valid = false; } } if (valid) { m_domainKey = domain.ToLower(CultureInfo.InvariantCulture); } } else { // for implicitly set domain AND at the set_default==false time // we simply got to match uri.Host against m_domain if (string.Compare(host, m_domain, StringComparison.OrdinalIgnoreCase) != 0) { valid = false; } } if(!valid) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, DomainAttributeName, m_domain)); } return false; } } //Check/Set Path if (set_default && m_path_implicit == true) { //assuming that uri path is always valid and contains at least one '/' switch (m_cookieVariant) { case CookieVariant.Plain: m_path = path; break; case CookieVariant.Rfc2109: m_path = path.Substring(0, path.LastIndexOf('/')); //may be empty break; case CookieVariant.Rfc2965: default: //hope future versions will have same 'Path' semantic? m_path = path.Substring(0, path.LastIndexOf('/')+1); break; } } else { //check current path (implicit/explicit) against given uri if (!path.StartsWith(CookieParser.CheckQuoted(m_path))) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, PathAttributeName, m_path)); } return false; } } // set the default port if Port attribute was present but had no value if (set_default && (m_port_implicit == false && m_port.Length == 0)) { m_port_list = new int[1] {port}; } if(m_port_implicit == false) { // Port must match agaist the one from the uri valid = false; foreach (int p in m_port_list) { if (p == port) { valid = true; break; } } if (!valid) { if (isThrow) { throw new CookieException(SR.GetString(SR.net_cookie_attribute, PortAttributeName, m_port)); } return false; } } return true; }
// According to spec we must assume default values for attributes but still // keep in mind that we must not include them into the requests. // We also check the validity of all attributes based on the version and variant (read RFC) // // To work properly this function must be called after cookie construction with // default (response) URI AND setDefault == true // // Afterwards, the function can be called many times with other URIs and // setDefault == false to check whether this cookie matches given uri internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDomain, string localDomain, bool setDefault, bool shouldThrow) { string host = uri.Host; int port = uri.Port; string path = uri.AbsolutePath; bool valid = true; if (setDefault) { // Set Variant. If version is zero => reset cookie to Version0 style if (Version == 0) { variant = CookieVariant.Plain; } else if (Version == 1 && variant == CookieVariant.Unknown) { // Since we don't expose Variant to an app, set it to Default variant = CookieVariant.Default; } m_cookieVariant = variant; } // Check the name if (m_name == null || m_name.Length == 0 || m_name[0] == '$' || m_name.IndexOfAny(ReservedToName) != -1) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, "Name", m_name == null ? "<null>" : m_name)); } return(false); } // Check the value if (m_value == null || (!(m_value.Length > 2 && m_value[0] == '\"' && m_value[m_value.Length - 1] == '\"') && m_value.IndexOfAny(ReservedToValue) != -1)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, "Value", m_value == null ? "<null>" : m_value)); } return(false); } // Check Comment syntax if (Comment != null && !(Comment.Length > 2 && Comment[0] == '\"' && Comment[Comment.Length - 1] == '\"') && (Comment.IndexOfAny(ReservedToValue) != -1)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.CommentAttributeName, Comment)); } return(false); } // Check Path syntax if (Path != null && !(Path.Length > 2 && Path[0] == '\"' && Path[Path.Length - 1] == '\"') && (Path.IndexOfAny(ReservedToValue) != -1)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.PathAttributeName, Path)); } return(false); } // Check/set domain // // If domain is implicit => assume a) uri is valid, b) just set domain to uri hostname. if (setDefault && m_domainImplicit == true) { m_domain = host; } else { if (!m_domainImplicit) { // Forwarding note: If Uri.Host is of IP address form then the only supported case // is for IMPLICIT domain property of a cookie. // The code below (explicit cookie.Domain value) will try to parse Uri.Host IP string // as a fqdn and reject the cookie. // Aliasing since we might need the KeyValue (but not the original one). string domain = m_domain; // Syntax check for Domain charset plus empty string. if (!DomainCharsTest(domain)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, domain == null ? "<null>" : domain)); } return(false); } // Domain must start with '.' if set explicitly. if (domain[0] != '.') { if (!(variant == CookieVariant.Rfc2965 || variant == CookieVariant.Plain)) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, m_domain)); } return(false); } domain = '.' + domain; } int host_dot = host.IndexOf('.'); // First quick check is for pushing a cookie into the local domain. if (isLocalDomain && string.Equals(localDomain, domain, StringComparison.OrdinalIgnoreCase)) { valid = true; } else if (domain.IndexOf('.', 1, domain.Length - 2) == -1) { // A single label domain is valid only if the domain is exactly the same as the host specified in the URI. if (!IsDomainEqualToHost(domain, host)) { valid = false; } } else if (variant == CookieVariant.Plain) { // We distinguish between Version0 cookie and other versions on domain issue. // According to Version0 spec a domain must be just a substring of the hostname. if (!IsDomainEqualToHost(domain, host)) { if (host.Length <= domain.Length || (string.Compare(host, host.Length - domain.Length, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0)) { valid = false; } } } else if (host_dot == -1 || domain.Length != host.Length - host_dot || (string.Compare(host, host_dot, domain, 0, domain.Length, StringComparison.OrdinalIgnoreCase) != 0)) { // Starting from the first dot, the host must match the domain. // // For null hosts, the host must match the domain exactly. if (!IsDomainEqualToHost(domain, host)) { valid = false; } } if (valid) { m_domainKey = domain.ToLowerInvariant(); } } else { // For implicitly set domain AND at the set_default == false time // we simply need to match uri.Host against m_domain. if (!string.Equals(host, m_domain, StringComparison.OrdinalIgnoreCase)) { valid = false; } } if (!valid) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, m_domain)); } return(false); } } // Check/Set Path if (setDefault && m_pathImplicit == true) { // This code assumes that the URI path is always valid and contains at least one '/'. switch (m_cookieVariant) { case CookieVariant.Plain: m_path = path; break; case CookieVariant.Rfc2109: m_path = path.Substring(0, path.LastIndexOf('/')); // May be empty break; case CookieVariant.Rfc2965: default: // NOTE: this code is not resilient against future versions with different 'Path' semantics. m_path = path.Substring(0, path.LastIndexOf('/') + 1); break; } } else { // Check current path (implicit/explicit) against given URI. if (!path.StartsWith(CookieParser.CheckQuoted(m_path))) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.PathAttributeName, m_path)); } return(false); } } // Set the default port if Port attribute was present but had no value. if (setDefault && (m_portImplicit == false && m_port.Length == 0)) { m_portList = new int[1] { port }; } if (m_portImplicit == false) { // Port must match against the one from the uri. valid = false; foreach (int p in m_portList) { if (p == port) { valid = true; break; } } if (!valid) { if (shouldThrow) { throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.PortAttributeName, m_port)); } return(false); } } return(true); }
internal CookieCollection CookieCutter(Uri uri, string headerName, string setCookieHeader, bool isThrow) { CookieCollection cookieCollection = new CookieCollection(); CookieVariant variant = CookieVariant.Unknown; if (headerName == null) { variant = CookieVariant.Rfc2109; } else { for (int index = 0; index < CookieContainer.HeaderInfo.Length; ++index) { if (string.Compare(headerName, CookieContainer.HeaderInfo[index].Name, StringComparison.OrdinalIgnoreCase) == 0) { variant = CookieContainer.HeaderInfo[index].Variant; } } } bool isLocalDomain = this.IsLocalDomain(uri.Host); try { CookieParser cookieParser = new CookieParser(setCookieHeader); while (true) { Cookie cookie; do { cookie = cookieParser.Get(); if (cookie != null) { if (ValidationHelper.IsBlankString(cookie.Name)) { if (isThrow) { throw new CookieException(SR.GetString("net_cookie_format")); } } } else { goto label_19; } }while (!cookie.VerifySetDefaults(variant, uri, isLocalDomain, this.m_fqdnMyDomain, true, isThrow)); cookieCollection.InternalAdd(cookie, true); } } catch (Exception ex) { if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException) { throw; } else if (isThrow) { throw new CookieException(SR.GetString("net_cookie_parse_header", new object[1] { (object)uri.AbsoluteUri }), ex); } } label_19: foreach (Cookie cookie in cookieCollection) { this.Add(cookie, isThrow); } return(cookieCollection); }