CookieContainer.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. //
  2. // System.Net.CookieContainer
  3. //
  4. // Authors:
  5. // Lawrence Pit ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. //
  8. // (c) 2003 Ximian, Inc. (http://www.ximian.com)
  9. //
  10. using System;
  11. using System.Collections;
  12. using System.Runtime.Serialization;
  13. using System.Text;
  14. namespace System.Net
  15. {
  16. [Serializable]
  17. public class CookieContainer
  18. {
  19. public const int DefaultCookieLengthLimit = 4096;
  20. public const int DefaultCookieLimit = 300;
  21. public const int DefaultPerDomainCookieLimit = 20;
  22. int count;
  23. int capacity = DefaultCookieLimit;
  24. int perDomainCapacity = DefaultPerDomainCookieLimit;
  25. int maxCookieSize = DefaultCookieLengthLimit;
  26. CookieCollection cookies;
  27. // ctors
  28. public CookieContainer ()
  29. {
  30. }
  31. public CookieContainer (int capacity)
  32. {
  33. if (capacity <= 0)
  34. throw new ArgumentException ("Must be greater than zero", "capacity");
  35. this.capacity = capacity;
  36. }
  37. public CookieContainer (int capacity, int perDomainCapacity, int maxCookieSize)
  38. : this (capacity)
  39. {
  40. if (perDomainCapacity <= 0 || perDomainCapacity < capacity)
  41. throw new ArgumentException ("Invalid value", "perDomaniCapacity");
  42. if (maxCookieSize <= 0)
  43. throw new ArgumentException ("Must be greater than zero", "maxCookieSize");
  44. this.perDomainCapacity = perDomainCapacity;
  45. this.maxCookieSize = maxCookieSize;
  46. }
  47. // properties
  48. public int Count {
  49. get { return count; }
  50. }
  51. public int Capacity {
  52. get { return capacity; }
  53. set {
  54. if ((value <= 0) ||
  55. (value < perDomainCapacity && perDomainCapacity != Int32.MaxValue))
  56. throw new ArgumentOutOfRangeException ("value");
  57. if (value < maxCookieSize)
  58. maxCookieSize = value;
  59. capacity = value;
  60. }
  61. }
  62. public int MaxCookieSize {
  63. get { return maxCookieSize; }
  64. set {
  65. if (value <= 0)
  66. throw new ArgumentOutOfRangeException ("value");
  67. maxCookieSize = value;
  68. }
  69. }
  70. public int PerDomainCapacity {
  71. get { return perDomainCapacity; }
  72. set {
  73. if ((value <= 0) ||
  74. (value > DefaultCookieLimit && value != Int32.MaxValue))
  75. throw new ArgumentOutOfRangeException ("value");
  76. if (value < perDomainCapacity)
  77. perDomainCapacity = value;
  78. perDomainCapacity = value;
  79. }
  80. }
  81. public void Add (Cookie cookie)
  82. {
  83. if (cookie == null)
  84. throw new ArgumentNullException ("cookie");
  85. if (cookie.Domain == null && cookie.Domain == "")
  86. throw new ArgumentException ("Cookie domain not set.", "cookie");
  87. if (cookie.Value.ToString ().Length > maxCookieSize)
  88. throw new CookieException ("Cookie size too big");
  89. AddCookie (cookie);
  90. }
  91. void AddCookie (Cookie cookie)
  92. {
  93. lock (this) {
  94. if (cookies == null)
  95. cookies = new CookieCollection ();
  96. if (count + 1 > capacity)
  97. throw new CookieException ("Capacity exceeded");
  98. cookies.Add (cookie);
  99. count++;
  100. }
  101. }
  102. public void Add (CookieCollection cookies)
  103. {
  104. if (cookies == null)
  105. throw new ArgumentNullException ("cookies");
  106. foreach (Cookie cookie in cookies)
  107. Add (cookie);
  108. }
  109. [MonoTODO ("Uri")]
  110. public void Add (Uri uri, Cookie cookie)
  111. {
  112. if (uri == null)
  113. throw new ArgumentNullException ("uri");
  114. Add (cookie);
  115. }
  116. [MonoTODO("Uri")]
  117. public void Add (Uri uri, CookieCollection cookies)
  118. {
  119. if (uri == null)
  120. throw new ArgumentNullException ("uri");
  121. Add (cookies);
  122. }
  123. [MonoTODO("Uri")]
  124. public string GetCookieHeader (Uri uri)
  125. {
  126. if (uri == null)
  127. throw new ArgumentNullException ("uri");
  128. if (cookies == null)
  129. return "";
  130. StringBuilder result = new StringBuilder ();
  131. bool notfirst = false;
  132. foreach (Cookie cookie in cookies) {
  133. if (notfirst)
  134. result.Append (';');
  135. result.Append (cookie.ToString ());
  136. notfirst = true;
  137. }
  138. return result.ToString ();
  139. }
  140. [MonoTODO("Uri")]
  141. public CookieCollection GetCookies (Uri uri)
  142. {
  143. if (uri == null)
  144. throw new ArgumentNullException ("uri");
  145. CookieCollection coll = new CookieCollection ();
  146. if (cookies == null)
  147. return coll;
  148. foreach (Cookie cookie in cookies)
  149. coll.Add (cookie);
  150. return coll;
  151. }
  152. public void SetCookies (Uri uri, string cookieHeader)
  153. {
  154. if (uri == null)
  155. throw new ArgumentNullException ("uri");
  156. if (cookieHeader == null)
  157. throw new ArgumentNullException ("cookieHeader");
  158. ParseAndAddCookies (cookieHeader);
  159. }
  160. // GetCookieValue, GetCookieName and ParseAndAddCookies copied from HttpRequest.cs
  161. static string GetCookieValue (string str, int length, ref int i)
  162. {
  163. if (i >= length)
  164. return null;
  165. int k = i;
  166. while (k < length && Char.IsWhiteSpace (str [k]))
  167. k++;
  168. int begin = k;
  169. while (k < length && str [k] != ';')
  170. k++;
  171. i = k;
  172. return str.Substring (begin, i - begin).Trim ();
  173. }
  174. static string GetCookieName (string str, int length, ref int i)
  175. {
  176. if (i >= length)
  177. return null;
  178. int k = i;
  179. while (k < length && Char.IsWhiteSpace (str [k]))
  180. k++;
  181. int begin = k;
  182. while (k < length && str [k] != ';' && str [k] != '=')
  183. k++;
  184. i = k + 1;
  185. return str.Substring (begin, k - begin).Trim ();
  186. }
  187. void ParseAndAddCookies (string header)
  188. {
  189. if (header.Length == 0)
  190. return;
  191. /* RFC 2109
  192. * cookie = "Cookie:" cookie-version
  193. * 1*((";" | ",") cookie-value)
  194. * cookie-value = NAME "=" VALUE [";" path] [";" domain]
  195. * cookie-version = "$Version" "=" value
  196. * NAME = attr
  197. * VALUE = value
  198. * path = "$Path" "=" value
  199. * domain = "$Domain" "=" value
  200. *
  201. * MS ignores $Version!
  202. * ',' as a separator produces errors.
  203. */
  204. string [] name_values = header.Trim ().Split (';');
  205. int length = name_values.Length;
  206. Cookie cookie = null;
  207. int pos;
  208. for (int i = 0; i < length; i++) {
  209. pos = 0;
  210. string name_value = name_values [i].Trim ();
  211. string name = GetCookieName (name_value, name_value.Length, ref pos);
  212. string value = GetCookieValue (name_value, name_value.Length, ref pos);
  213. if (cookie != null) {
  214. if (name == "$Path") {
  215. cookie.Path = value;
  216. continue;
  217. } else if (name == "$Domain") {
  218. cookie.Domain = value;
  219. continue;
  220. } else {
  221. Add (cookie);
  222. cookie = null;
  223. }
  224. }
  225. cookie = new Cookie (name, value);
  226. }
  227. if (cookie != null)
  228. Add (cookie);
  229. }
  230. } // CookieContainer
  231. } // System.Net