CookieHelper.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SocketHttpListener.Net
  9. {
  10. public static class CookieHelper
  11. {
  12. internal static CookieCollection Parse(string value, bool response)
  13. {
  14. return response
  15. ? parseResponse(value)
  16. : null;
  17. }
  18. private static string[] splitCookieHeaderValue(string value)
  19. {
  20. return new List<string>(value.SplitHeaderValue(',', ';')).ToArray();
  21. }
  22. private static CookieCollection parseResponse(string value)
  23. {
  24. var cookies = new CookieCollection();
  25. Cookie cookie = null;
  26. var pairs = splitCookieHeaderValue(value);
  27. for (int i = 0; i < pairs.Length; i++)
  28. {
  29. var pair = pairs[i].Trim();
  30. if (pair.Length == 0)
  31. continue;
  32. if (pair.StartsWith("version", StringComparison.OrdinalIgnoreCase))
  33. {
  34. if (cookie != null)
  35. cookie.Version = Int32.Parse(pair.GetValueInternal("=").Trim('"'));
  36. }
  37. else if (pair.StartsWith("expires", StringComparison.OrdinalIgnoreCase))
  38. {
  39. var buffer = new StringBuilder(pair.GetValueInternal("="), 32);
  40. if (i < pairs.Length - 1)
  41. buffer.AppendFormat(", {0}", pairs[++i].Trim());
  42. DateTime expires;
  43. if (!DateTime.TryParseExact(
  44. buffer.ToString(),
  45. new[] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" },
  46. new CultureInfo("en-US"),
  47. DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal,
  48. out expires))
  49. expires = DateTime.Now;
  50. if (cookie != null && cookie.Expires == DateTime.MinValue)
  51. cookie.Expires = expires.ToLocalTime();
  52. }
  53. else if (pair.StartsWith("max-age", StringComparison.OrdinalIgnoreCase))
  54. {
  55. var max = Int32.Parse(pair.GetValueInternal("=").Trim('"'));
  56. var expires = DateTime.Now.AddSeconds((double)max);
  57. if (cookie != null)
  58. cookie.Expires = expires;
  59. }
  60. else if (pair.StartsWith("path", StringComparison.OrdinalIgnoreCase))
  61. {
  62. if (cookie != null)
  63. cookie.Path = pair.GetValueInternal("=");
  64. }
  65. else if (pair.StartsWith("domain", StringComparison.OrdinalIgnoreCase))
  66. {
  67. if (cookie != null)
  68. cookie.Domain = pair.GetValueInternal("=");
  69. }
  70. else if (pair.StartsWith("port", StringComparison.OrdinalIgnoreCase))
  71. {
  72. var port = pair.Equals("port", StringComparison.OrdinalIgnoreCase)
  73. ? "\"\""
  74. : pair.GetValueInternal("=");
  75. if (cookie != null)
  76. cookie.Port = port;
  77. }
  78. else if (pair.StartsWith("comment", StringComparison.OrdinalIgnoreCase))
  79. {
  80. if (cookie != null)
  81. cookie.Comment = pair.GetValueInternal("=").UrlDecode();
  82. }
  83. else if (pair.StartsWith("commenturl", StringComparison.OrdinalIgnoreCase))
  84. {
  85. if (cookie != null)
  86. cookie.CommentUri = pair.GetValueInternal("=").Trim('"').ToUri();
  87. }
  88. else if (pair.StartsWith("discard", StringComparison.OrdinalIgnoreCase))
  89. {
  90. if (cookie != null)
  91. cookie.Discard = true;
  92. }
  93. else if (pair.StartsWith("secure", StringComparison.OrdinalIgnoreCase))
  94. {
  95. if (cookie != null)
  96. cookie.Secure = true;
  97. }
  98. else if (pair.StartsWith("httponly", StringComparison.OrdinalIgnoreCase))
  99. {
  100. if (cookie != null)
  101. cookie.HttpOnly = true;
  102. }
  103. else
  104. {
  105. if (cookie != null)
  106. cookies.Add(cookie);
  107. string name;
  108. string val = String.Empty;
  109. var pos = pair.IndexOf('=');
  110. if (pos == -1)
  111. {
  112. name = pair;
  113. }
  114. else if (pos == pair.Length - 1)
  115. {
  116. name = pair.Substring(0, pos).TrimEnd(' ');
  117. }
  118. else
  119. {
  120. name = pair.Substring(0, pos).TrimEnd(' ');
  121. val = pair.Substring(pos + 1).TrimStart(' ');
  122. }
  123. cookie = new Cookie(name, val);
  124. }
  125. }
  126. if (cookie != null)
  127. cookies.Add(cookie);
  128. return cookies;
  129. }
  130. }
  131. }