using System.Net;
namespace XFESystem.Browser;
public interface IWebCookieStore
{
string ReadDocumentCookies(Uri address);
void WriteDocumentCookie(Uri address, string value);
}
/// <summary>Bounded session cookies shared by HTTP and document.cookie. No host profile import.</summary>
public sealed class BrowserCookieStore : IWebCookieStore
{
private readonly CookieContainer cookies = new(256, 32, 4096);
private readonly object gate = new();
public string RequestHeader(Uri address) { lock (gate) return cookies.GetCookieHeader(address); }
public void Receive(Uri address, string header)
{
if (header.Length > 4096) return;
lock (gate) { try { cookies.SetCookies(address, header); } catch (CookieException) { } }
}
public string ReadDocumentCookies(Uri address)
{
lock (gate) return string.Join("; ", cookies.GetCookies(address).Cast<Cookie>().Where(c => !c.HttpOnly).Select(c => c.Name + "=" + c.Value));
}
public void WriteDocumentCookie(Uri address, string value)
{
if (value.Length > 4096 || value.Any(c => c is '\r' or '\n' or '\0')) return;
// Script cannot create HttpOnly cookies or overwrite an existing one.
string name = value.Split(';')[0].Split('=')[0].Trim();
if (value.Split(';').Skip(1).Any(p => p.Trim().Equals("httponly", StringComparison.OrdinalIgnoreCase))) return;
lock (gate)
{
if (cookies.GetCookies(address).Cast<Cookie>().Any(c => c.HttpOnly && c.Name == name)) return;
try { cookies.SetCookies(address, value); } catch (CookieException) { }
}
}
}
using System.Net;
namespace XFESystem.Browser;
public interface IWebCookieStore
{
string ReadDocumentCookies(Uri address);
void WriteDocumentCookie(Uri address, string value);
}
/// <summary>Bounded session cookies shared by HTTP and document.cookie. No host profile import.</summary>
public sealed class BrowserCookieStore : IWebCookieStore
{
private readonly CookieContainer cookies = new(256, 32, 4096);
private readonly object gate = new();
public string RequestHeader(Uri address) { lock (gate) return cookies.GetCookieHeader(address); }
public void Receive(Uri address, string header)
{
if (header.Length > 4096) return;
lock (gate) { try { cookies.SetCookies(address, header); } catch (CookieException) { } }
}
public string ReadDocumentCookies(Uri address)
{
lock (gate) return string.Join("; ", cookies.GetCookies(address).Cast<Cookie>().Where(c => !c.HttpOnly).Select(c => c.Name + "=" + c.Value));
}
public void WriteDocumentCookie(Uri address, string value)
{
if (value.Length > 4096 || value.Any(c => c is '\r' or '\n' or '\0')) return;
// Script cannot create HttpOnly cookies or overwrite an existing one.
string name = value.Split(';')[0].Split('=')[0].Trim();
if (value.Split(';').Skip(1).Any(p => p.Trim().Equals("httponly", StringComparison.OrdinalIgnoreCase))) return;
lock (gate)
{
if (cookies.GetCookies(address).Cast<Cookie>().Any(c => c.HttpOnly && c.Name == name)) return;
try { cookies.SetCookies(address, value); } catch (CookieException) { }
}
}
}