Skip to content

Commit bcd310f

Browse files
committed
Implemented set / get algorithm
1 parent e1a57f9 commit bcd310f

File tree

1 file changed

+104
-6
lines changed

1 file changed

+104
-6
lines changed

src/AngleSharp.Io/Cookie/AdvancedCookieProvider.cs

Lines changed: 104 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,89 @@ public AdvancedCookieProvider(IFileHandler handler, AdvancedCookieProviderOption
3535

3636
String ICookieProvider.GetCookie(Url url)
3737
{
38-
throw new NotImplementedException();
38+
var host = CanonicalDomain(url.HostName);
39+
var path = String.IsNullOrEmpty(url.Path) ? "/" : url.Path;
40+
var secure = url.Scheme.IsOneOf(ProtocolNames.Https, ProtocolNames.Wss);
41+
var now = DateTime.UtcNow;
42+
var cookies = FindCookies(host, path)
43+
.ToArray()
44+
.Where(c =>
45+
{
46+
if (c.IsHostOnly ?? false)
47+
{
48+
if (!c.Domain.Is(host))
49+
{
50+
return false;
51+
}
52+
}
53+
else if (!DomainMatch(host, c.Domain, false))
54+
{
55+
return false;
56+
}
57+
58+
if (!CheckPaths(path, c.Path))
59+
{
60+
return false;
61+
}
62+
63+
// "If the cookie's secure-only-flag is true, then the request-uri's
64+
// scheme must denote a "secure" protocol"
65+
if (c.IsSecure && !secure)
66+
{
67+
return false;
68+
}
69+
70+
// deferred from Section 5.3
71+
// non-RFC: allow retention of expired cookies by choice
72+
if (c.ComputeExpiration(now) <= now)
73+
{
74+
RemoveCookie(c.Domain, c.Path, c.Key);
75+
return false;
76+
}
77+
78+
return true;
79+
})
80+
.Select(c => c.ToGetCookie())
81+
.ToArray();
82+
return String.Join("; ", cookies);
3983
}
4084

4185
void ICookieProvider.SetCookie(Url url, String value)
4286
{
43-
throw new NotImplementedException();
87+
var host = CanonicalDomain(url.HostName);
88+
var cookie = WebCookie.FromString(value);
89+
90+
if (cookie != null)
91+
{
92+
if (!String.IsNullOrEmpty(cookie.Domain))
93+
{
94+
var cdom = cookie.CanonicalDomain;
95+
var suffix = GetPublicSuffix(cdom);
96+
97+
if (suffix == null || !DomainMatch(host, cdom, false))
98+
{
99+
return;
100+
}
101+
102+
// don't reset if already set
103+
if (!cookie.IsHostOnly.HasValue)
104+
{
105+
cookie.IsHostOnly = false;
106+
}
107+
}
108+
else
109+
{
110+
cookie.Domain = host;
111+
cookie.IsHostOnly = true;
112+
}
113+
114+
if (String.IsNullOrEmpty(cookie.Path) || cookie.Path[0] != '/')
115+
{
116+
cookie.Path = GetDefaultPath(url.Path);
117+
}
118+
119+
AddCookie(cookie);
120+
}
44121
}
45122

46123
/// <summary>
@@ -87,9 +164,11 @@ public IEnumerable<WebCookie> FindCookies(String domain, String path = null)
87164
/// <param name="cookie">The cookie to add.</param>
88165
public void AddCookie(WebCookie cookie)
89166
{
90-
_cookies.Remove(FindCookie(cookie.Domain, cookie.Path, cookie.Key));
91-
_cookies.Add(cookie);
92-
WriteCookies();
167+
if (cookie != null)
168+
{
169+
_cookies.Remove(FindCookie(cookie.Domain, cookie.Path, cookie.Key));
170+
InsertCookie(cookie);
171+
}
93172
}
94173

95174
/// <summary>
@@ -99,7 +178,11 @@ public void AddCookie(WebCookie cookie)
99178
/// <param name="newCookie">The updated cookie content.</param>
100179
public void UpdateCookie(WebCookie oldCookie, WebCookie newCookie)
101180
{
102-
_cookies.Remove(FindCookie(oldCookie.Domain, oldCookie.Path, oldCookie.Key));
181+
if (oldCookie != null)
182+
{
183+
_cookies.Remove(FindCookie(oldCookie.Domain, oldCookie.Path, oldCookie.Key));
184+
}
185+
103186
AddCookie(newCookie);
104187
}
105188

@@ -155,6 +238,21 @@ public IEnumerable<WebCookie> RemoveAllCookies()
155238

156239
private List<WebCookie> ReadCookies() => Deserialize(_handler.ReadFile(), _forceParse, _httpOnlyExtension);
157240

241+
private void InsertCookie(WebCookie cookie)
242+
{
243+
for (var i = 0; i < _cookies.Count; i++)
244+
{
245+
if (cookie.CompareTo(_cookies[i]) > 0)
246+
{
247+
_cookies.Insert(i, cookie);
248+
return;
249+
}
250+
}
251+
252+
_cookies.Add(cookie);
253+
WriteCookies();
254+
}
255+
158256
private void WriteCookies()
159257
{
160258
var selection = _cookies.Where(m => m.IsPersistent);

0 commit comments

Comments
 (0)