123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
- using System;
- using System.Collections.Generic;
- using BestHTTP.Extensions;
- using System.IO;
- namespace BestHTTP.Cookies
- {
-
-
-
- public sealed class Cookie : IComparable<Cookie>, IEquatable<Cookie>
- {
- private const int Version = 1;
- #region Public Properties
-
-
-
- public string Name { get; private set; }
-
-
-
- public string Value { get; private set; }
-
-
-
- public DateTime Date { get; internal set; }
-
-
-
- public DateTime LastAccess { get; set; }
-
-
-
-
-
- public DateTime Expires { get; private set; }
-
-
-
-
-
- public long MaxAge { get; private set; }
-
-
-
- public bool IsSession { get; private set; }
-
-
-
-
-
-
- public string Domain { get; private set; }
-
-
-
-
- public string Path { get; private set; }
-
-
-
-
-
- public bool IsSecure { get; private set; }
-
-
-
-
-
- public bool IsHttpOnly { get; private set; }
- #endregion
- #region Public Constructors
- public Cookie(string name, string value)
- :this(name, value, "/", string.Empty)
- {}
- public Cookie(string name, string value, string path)
- : this(name, value, path, string.Empty)
- {}
- public Cookie(string name, string value, string path, string domain)
- :this()
- {
- this.Name = name;
- this.Value = value;
- this.Path = path;
- this.Domain = domain;
- }
- public Cookie(Uri uri, string name, string value, DateTime expires, bool isSession = true)
- :this(name, value, uri.AbsolutePath, uri.Host)
- {
- this.Expires = expires;
- this.IsSession = isSession;
- this.Date = DateTime.UtcNow;
- }
- public Cookie(Uri uri, string name, string value, long maxAge = -1, bool isSession = true)
- :this(name, value, uri.AbsolutePath, uri.Host)
- {
- this.MaxAge = maxAge;
- this.IsSession = isSession;
- this.Date = DateTime.UtcNow;
- }
- #endregion
- internal Cookie()
- {
-
-
- IsSession = true;
- MaxAge = -1;
- LastAccess = DateTime.UtcNow;
- }
- public bool WillExpireInTheFuture()
- {
-
- if (IsSession)
- return true;
-
- return MaxAge != -1 ?
- Math.Max(0, (long)(DateTime.UtcNow - Date).TotalSeconds) < MaxAge :
- Expires > DateTime.UtcNow;
- }
-
-
-
-
- public uint GuessSize()
- {
- return (uint)((Name != null ? Name.Length * sizeof(char) : 0) +
- (Value != null ? Value.Length * sizeof(char) : 0) +
- (Domain != null ? Domain.Length * sizeof(char) : 0) +
- (Path != null ? Path.Length * sizeof(char) : 0) +
- (sizeof(long) * 4) +
- (sizeof(bool) * 3));
- }
- public static Cookie Parse(string header, Uri defaultDomain)
- {
- Cookie cookie = new Cookie();
- try
- {
- var kvps = ParseCookieHeader(header);
- foreach (var kvp in kvps)
- {
- switch (kvp.Key.ToLowerInvariant())
- {
- case "path":
-
-
- cookie.Path = string.IsNullOrEmpty(kvp.Value) || !kvp.Value.StartsWith("/") ? "/" : cookie.Path = kvp.Value;
- break;
- case "domain":
-
- if (string.IsNullOrEmpty(kvp.Value))
- return null;
-
-
- cookie.Domain = kvp.Value.StartsWith(".") ? kvp.Value.Substring(1) : kvp.Value;
- break;
- case "expires":
- cookie.Expires = kvp.Value.ToDateTime(DateTime.FromBinary(0));
- cookie.IsSession = false;
- break;
- case "max-age":
- cookie.MaxAge = kvp.Value.ToInt64(-1);
- cookie.IsSession = false;
- break;
- case "secure":
- cookie.IsSecure = true;
- break;
- case "httponly":
- cookie.IsHttpOnly = true;
- break;
- default:
- cookie.Name = kvp.Key;
- cookie.Value = kvp.Value;
- break;
- }
- }
-
-
- if (HTTPManager.EnablePrivateBrowsing)
- cookie.IsSession = true;
-
-
-
- if (string.IsNullOrEmpty(cookie.Domain))
- cookie.Domain = defaultDomain.Host;
-
-
-
-
- if (string.IsNullOrEmpty(cookie.Path))
- cookie.Path = defaultDomain.AbsolutePath;
- cookie.Date = cookie.LastAccess = DateTime.UtcNow;
- }
- catch
- {
- }
- return cookie;
- }
- #region Save & Load
- internal void SaveTo(BinaryWriter stream)
- {
- stream.Write(Version);
- stream.Write(Name ?? string.Empty);
- stream.Write(Value ?? string.Empty);
- stream.Write(Date.ToBinary());
- stream.Write(LastAccess.ToBinary());
- stream.Write(Expires.ToBinary());
- stream.Write(MaxAge);
- stream.Write(IsSession);
- stream.Write(Domain ?? string.Empty);
- stream.Write(Path ?? string.Empty);
- stream.Write(IsSecure);
- stream.Write(IsHttpOnly);
- }
- internal void LoadFrom(BinaryReader stream)
- {
- stream.ReadInt32();
- this.Name = stream.ReadString();
- this.Value = stream.ReadString();
- this.Date = DateTime.FromBinary(stream.ReadInt64());
- this.LastAccess = DateTime.FromBinary(stream.ReadInt64());
- this.Expires = DateTime.FromBinary(stream.ReadInt64());
- this.MaxAge = stream.ReadInt64();
- this.IsSession = stream.ReadBoolean();
- this.Domain = stream.ReadString();
- this.Path = stream.ReadString();
- this.IsSecure = stream.ReadBoolean();
- this.IsHttpOnly = stream.ReadBoolean();
- }
- #endregion
- #region Overrides and new Equals function
- public override string ToString()
- {
- return string.Concat(this.Name, "=", this.Value);
- }
- public override bool Equals(object obj)
- {
- if (obj == null)
- return false;
- return this.Equals(obj as Cookie);
- }
- public bool Equals(Cookie cookie)
- {
- if (cookie == null)
- return false;
- if (Object.ReferenceEquals(this, cookie))
- return true;
- return this.Name.Equals(cookie.Name, StringComparison.Ordinal) &&
- ((this.Domain == null && cookie.Domain == null) || this.Domain.Equals(cookie.Domain, StringComparison.Ordinal)) &&
- ((this.Path == null && cookie.Path == null) || this.Path.Equals(cookie.Path, StringComparison.Ordinal));
- }
- public override int GetHashCode()
- {
- return this.ToString().GetHashCode();
- }
- #endregion
- #region Private Helper Functions
- private static string ReadValue(string str, ref int pos)
- {
- string result = string.Empty;
- if (str == null)
- return result;
- return str.Read(ref pos, ';');
- }
- private static List<HeaderValue> ParseCookieHeader(string str)
- {
- List<HeaderValue> result = new List<HeaderValue>();
- if (str == null)
- return result;
- int idx = 0;
-
- while (idx < str.Length)
- {
-
- string key = str.Read(ref idx, (ch) => ch != '=' && ch != ';').Trim();
- HeaderValue qp = new HeaderValue(key);
- if (idx < str.Length && str[idx - 1] == '=')
- qp.Value = ReadValue(str, ref idx);
- result.Add(qp);
- }
- return result;
- }
- #endregion
- #region IComparable<Cookie> implementation
- public int CompareTo(Cookie other)
- {
- return this.LastAccess.CompareTo(other.LastAccess);
- }
- #endregion
- }
- }
- #endif
|