CookieHelper.cs 5.3 KB

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