private void BuildCookieCollectionFromDomainMatches(Uri uri, bool isSecure, int port, CookieCollection cookies, List <string> domainAttribute, bool matchOnlyPlainCookie) { for (int i = 0; i < domainAttribute.Count; i++) { bool found = false; bool defaultAdded = false; PathList pathList; lock (_domainTable) { _domainTable.TryGetValue(domainAttribute[i], out pathList); } if (pathList == null) { continue; } lock (pathList.SyncRoot) { foreach (DictionaryEntry entry in pathList) { string path = (string)entry.Key; if (uri.AbsolutePath.StartsWith(CookieParser.CheckQuoted(path))) { found = true; CookieCollection cc = (CookieCollection)entry.Value; cc.TimeStamp(CookieCollection.Stamp.Set); MergeUpdateCollections(cookies, cc, port, isSecure, matchOnlyPlainCookie); if (path == "/") { defaultAdded = true; } } else if (found) { break; } } } if (!defaultAdded) { CookieCollection cc = (CookieCollection)pathList["/"]; if (cc != null) { cc.TimeStamp(CookieCollection.Stamp.Set); MergeUpdateCollections(cookies, cc, port, isSecure, matchOnlyPlainCookie); } } // Remove unused domain // (This is the only place that does domain removal) if (pathList.Count == 0) { AddRemoveDomain(domainAttribute[i], null); } } }
// 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_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 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_path_implicit == 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_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 InternalGetCookies(Uri uri) { bool isSecure = (uri.Scheme == Uri.UriSchemeHttps); int port = uri.Port; CookieCollection cookies = new CookieCollection(); ArrayList nameKeys = new ArrayList(); int firstCompatibleVersion0SpecKey = 0; string fqdnRemote = uri.Host; int dot = fqdnRemote.IndexOf('.'); if (dot == -1) { // DNS.resolve may return short names even for other inet domains ;-( // We _don't_ know what the exact domain is, so try also grab short hostname cookies. nameKeys.Add(fqdnRemote); // add a preceding dot (null host) nameKeys.Add("." + fqdnRemote); // grab long name from the local domain if (m_fqdnMyDomain != null && m_fqdnMyDomain.Length != 0) { nameKeys.Add(fqdnRemote + m_fqdnMyDomain); // grab the local domain itself nameKeys.Add(m_fqdnMyDomain); firstCompatibleVersion0SpecKey = 3; } else { firstCompatibleVersion0SpecKey = 1; } } else { // grab the host itself nameKeys.Add(fqdnRemote); // add a preceding dot (null host) nameKeys.Add("." + fqdnRemote); // grab the host domain nameKeys.Add(fqdnRemote.Substring(dot)); firstCompatibleVersion0SpecKey = 2; // The following block is only for compatibility with Version0 spec. // Still, we'll add only Plain-Variant cookies if found under below keys if (fqdnRemote.Length > 2) { // We ignore the '.' at the end on the name int last = fqdnRemote.LastIndexOf('.', fqdnRemote.Length - 2); //AND keys with <2 dots inside. if (last > 0) { last = fqdnRemote.LastIndexOf('.', last - 1); } if (last != -1) { while ((dot < last) && (dot = fqdnRemote.IndexOf('.', dot + 1)) != -1) { nameKeys.Add(fqdnRemote.Substring(dot)); } } } } foreach (string key in nameKeys) { bool found = false; bool defaultAdded = false; PathList pathList; lock (m_domainTable.SyncRoot) { pathList = (PathList)m_domainTable[key]; } --firstCompatibleVersion0SpecKey; if (pathList == null) { continue; } lock (pathList.SyncRoot) { foreach (DictionaryEntry entry in pathList) { string path = (string)entry.Key; if (uri.AbsolutePath.StartsWith(CookieParser.CheckQuoted(path))) { found = true; CookieCollection cc = (CookieCollection)entry.Value; cc.TimeStamp(CookieCollection.Stamp.Set); MergeUpdateCollections(cookies, cc, port, isSecure, (firstCompatibleVersion0SpecKey < 0)); if (path == "/") { defaultAdded = true; } } else if (found) { break; } } } if (!defaultAdded) { CookieCollection cc = (CookieCollection)pathList["/"]; if (cc != null) { cc.TimeStamp(CookieCollection.Stamp.Set); MergeUpdateCollections(cookies, cc, port, isSecure, (firstCompatibleVersion0SpecKey < 0)); } } // Remove unused domain // (This is the only place that does domain removal) if (pathList.Count == 0) { AddRemoveDomain(key, null); } } return(cookies); }
private void BuildCookieCollectionFromDomainMatches(Uri uri, bool isSecure, int port, ref CookieCollection cookies, System.Collections.Generic.List <string> domainAttribute, bool matchOnlyPlainCookie) { for (int i = 0; i < domainAttribute.Count; i++) { bool found = false; bool defaultAdded = false; PathList pathList; lock (m_domainTable.SyncRoot) { pathList = (PathList)m_domainTable[domainAttribute[i]]; if (pathList == null) { continue; } } lock (pathList.SyncRoot) { // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations. IDictionaryEnumerator e = pathList.GetEnumerator(); while (e.MoveNext()) { string path = (string)e.Key; if (uri.AbsolutePath.StartsWith(CookieParser.CheckQuoted(path))) { found = true; CookieCollection cc = (CookieCollection)e.Value; cc.TimeStamp(CookieCollection.Stamp.Set); MergeUpdateCollections(ref cookies, cc, port, isSecure, matchOnlyPlainCookie); if (path == "/") { defaultAdded = true; } } else if (found) { break; } } } if (!defaultAdded) { CookieCollection cc = (CookieCollection)pathList["/"]; if (cc != null) { cc.TimeStamp(CookieCollection.Stamp.Set); MergeUpdateCollections(ref cookies, cc, port, isSecure, matchOnlyPlainCookie); } } // Remove unused domain // (This is the only place that does domain removal) if (pathList.Count == 0) { lock (m_domainTable.SyncRoot) { m_domainTable.Remove(domainAttribute[i]); } } } }
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 InternalGetCookies(Uri uri) { bool isSecure = uri.Scheme == Uri.UriSchemeHttps; int port = uri.Port; CookieCollection destination = new CookieCollection(); ArrayList arrayList = new ArrayList(); string host = uri.Host; int startIndex = host.IndexOf('.'); int num1; if (startIndex == -1) { arrayList.Add((object)host); arrayList.Add((object)("." + host)); if (this.m_fqdnMyDomain != null && this.m_fqdnMyDomain.Length != 0) { arrayList.Add((object)(host + this.m_fqdnMyDomain)); arrayList.Add((object)this.m_fqdnMyDomain); num1 = 3; } else { num1 = 1; } } else { arrayList.Add((object)host); arrayList.Add((object)("." + host)); arrayList.Add((object)host.Substring(startIndex)); num1 = 2; if (host.Length > 2) { int num2 = host.LastIndexOf('.', host.Length - 2); if (num2 > 0) { num2 = host.LastIndexOf('.', num2 - 1); } if (num2 != -1) { while (startIndex < num2 && (startIndex = host.IndexOf('.', startIndex + 1)) != -1) { arrayList.Add((object)host.Substring(startIndex)); } } } } foreach (string key in arrayList) { bool flag1 = false; bool flag2 = false; PathList pathList = (PathList)this.m_domainTable[(object)key]; --num1; if (pathList != null) { foreach (DictionaryEntry dictionaryEntry in pathList) { string str = (string)dictionaryEntry.Key; if (uri.AbsolutePath.StartsWith(CookieParser.CheckQuoted(str))) { flag1 = true; CookieCollection source = (CookieCollection)dictionaryEntry.Value; source.TimeStamp(CookieCollection.Stamp.Set); this.MergeUpdateCollections(destination, source, port, isSecure, num1 < 0); if (str == "/") { flag2 = true; } } else if (flag1) { break; } } if (!flag2) { CookieCollection source = (CookieCollection)pathList["/"]; if (source != null) { source.TimeStamp(CookieCollection.Stamp.Set); this.MergeUpdateCollections(destination, source, port, isSecure, num1 < 0); } } if (pathList.Count == 0) { this.AddRemoveDomain(key, (PathList)null); } } } return(destination); }